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

From Second Life Wiki
Jump to navigation Jump to search
m (partial update)
m (+Finding a Local Point for a Self offset)
Line 9: Line 9:
|title=Rotation Frames Explained
|title=Rotation Frames Explained
|content=
|content=
A Rotation Frame is the coordinate axis around which a rotation operates, there are three possible frames to operate in
A Rotation Frame is the coordinate axis around which a rotation operates, there are four possible frames to operate in
* Global Frame is the top level default axis. There are two equal but separate Global Frames
* Global Frame is the top level default axis. There are two equal but separate Global Frames
** Region Frame: Regions have a default frame that is East(+X or +Red), North(+Y or +Green), and Higher(+Z or +Blue). (negative values are the opposite direction)
** Region Frame: Regions have a default frame that is East(+X or +Red), North(+Y or +Green), and Higher(+Z or +Blue). (negative values are the opposite direction)
** Attachment Frame: Attachment points have their own separate frame for each point. These frames do not change when the avatar is moving, but will appear to change in relation to the region frame as the avatar moves or is animated
** Attachment Frame: Attachment points have their own separate frame for each point. This frame does not change in relation to the attachment point when the avatar is moving, but will appear to change in relation to the region frame as the avatar moves or is animated
* Reference Frame: this is the frame defined by the referenced prim itself. usually referred to as "it own axis".
* Self Frame: this is the frame defined by the object you are working on itself. usually referred to as "it own axis".
** has default coordinates of Front(+X or +Red), Left(+Y or +Green), and Above(+Z or +Blue), that match the prim's axis (negative values are the opposite direction)
** has default coordinates of Front(+X or +Red), Left(+Y or +Green), and Above(+Z or +Blue), that match the prim's axis (negative values are the opposite direction)
** A Region's or Attachment Point's Reference Frame is the same as the Global Frame
** A Region's or Attachment Point's Self Frame is the same as the Global Frame
* Local Frame: This is the same as the Reference Frame of the next highest connection.
** IMPORTANT: this frame is (erroneously) called "local" in the build tools edit window (the error comes from using a different definition of the word local)
** the Local Frame of a child prim is the root prim's Reference Frame
* Local Frame: This is the same as the Self Frame of the next highest connection.
** the Local Frame of a child prim is the root prim's Self Frame
** the Local Frame of a root prim is the Region or Attachment Point (so, the same as the Global Frame)
** the Local Frame of a root prim is the Region or Attachment Point (so, the same as the Global Frame)
* Reference Frame (special case): this is the frame of something else that is not the object you are working on
** If your Reference Frame is the Root of a child prim being worked on, it's the same as the Local Frame
** If your Reference Frame is the Region or Attachment point, it's the same as the Global Frame
** The only time a Reference Frame is different than the previous two is when the reference frame (and the object or prim) shares the same Global Frame, but is NOT a parent of the object or prim you are working on.
*** For simplicity, the remainder of this article does not use the Reference Frame, simply because it's not used in any common rotation tasks.
}}
}}


Line 52: Line 58:
|title=Representing Rotations
|title=Representing Rotations
|content=
|content=
* There are three simple programmatically useful ways to represent rotations in a script
* There are three simple programmatically useful ways to represent rotations in LSL
** as a [[vector]] of degrees (which you can easily read or write)
** as a [[vector]] of degrees (which most people can easily read or write)
** as a [[vector]] of radians (which are understood by functions like [[llTargetOmega]])
** as a [[vector]] of radians (which are understood by functions like [[llTargetOmega]])
** as a [[rotation]] quaternion (which are understood by functions that set rotations)
** as a [[rotation]] quaternion (which are understood by functions that set rotations)
Line 105: Line 111:
** The order that you add rotation in changes the rotation frame that the operation works on (detailed below)
** The order that you add rotation in changes the rotation frame that the operation works on (detailed below)
** Do not use the "/" operator for anything but rotation reversal, as it's rules are slightly in the behavior frame and can give unexpected results
** Do not use the "/" operator for anything but rotation reversal, as it's rules are slightly in the behavior frame and can give unexpected results
* To rotate in the Reference Frame:
* To rotate in the Self Frame (prim's own axis):
** (vRotAmount2ChangeBy * vRotCurrentLocal)
** (vRotAmount2ChangeBy * vRotCurrentLocal)
* To rotate in the Local Frame:
* To rotate in the Local Frame:
Line 114: Line 120:


{{void-box
{{void-box
|title=Rotating a Point Relative to the Prim
|title=Finding a Local Point for a Self offset
|content=
|content=
* Being rewritten
Let's say you want to know the Local coordinates of a point that is 1 meter in front (positive self x axis) of your object (like one might use for a gun, or product rezzor), no matter how the object is rotated.
<lsl> vPosOffset = <1.0, 0.0, 0.0>; //-- the distance and direction from your objects center to the point we want, in local frame.
vPosLocal = (vPosOffset * llGetLocalRot()) + llGetPos(); //-- multiply by the local rotation and add the local position</lsl>
* For a child prim needing a global point, treat the point calculated above from the child as a self offset to the root and repeat the steps using that point and the values for the root.
'''IMPOTANT NOTE''': the llRez* functions always use the avatars position and rotation for the root when used in attachments. make sure you use functions that get the avatar values when rezzing from attachments.
}}
}}



Revision as of 08:45, 4 October 2011

Common Rotation Tasks Simplified

This page is for people (like myself) who find the 'official' page on rotations to be either too complicated or have information that doesn't help you. This page walks you step by step through how to do the basic things to get the results you want, without looking under the hood too much. first a few definitions, then the basics, and then a few examples of common things you might want to do.

Rotation Frames Explained

A Rotation Frame is the coordinate axis around which a rotation operates, there are four possible frames to operate in

  • Global Frame is the top level default axis. There are two equal but separate Global Frames
    • Region Frame: Regions have a default frame that is East(+X or +Red), North(+Y or +Green), and Higher(+Z or +Blue). (negative values are the opposite direction)
    • Attachment Frame: Attachment points have their own separate frame for each point. This frame does not change in relation to the attachment point when the avatar is moving, but will appear to change in relation to the region frame as the avatar moves or is animated
  • Self Frame: this is the frame defined by the object you are working on itself. usually referred to as "it own axis".
    • has default coordinates of Front(+X or +Red), Left(+Y or +Green), and Above(+Z or +Blue), that match the prim's axis (negative values are the opposite direction)
    • A Region's or Attachment Point's Self Frame is the same as the Global Frame
    • IMPORTANT: this frame is (erroneously) called "local" in the build tools edit window (the error comes from using a different definition of the word local)
  • Local Frame: This is the same as the Self Frame of the next highest connection.
    • the Local Frame of a child prim is the root prim's Self Frame
    • the Local Frame of a root prim is the Region or Attachment Point (so, the same as the Global Frame)
  • Reference Frame (special case): this is the frame of something else that is not the object you are working on
    • If your Reference Frame is the Root of a child prim being worked on, it's the same as the Local Frame
    • If your Reference Frame is the Region or Attachment point, it's the same as the Global Frame
    • The only time a Reference Frame is different than the previous two is when the reference frame (and the object or prim) shares the same Global Frame, but is NOT a parent of the object or prim you are working on.
      • For simplicity, the remainder of this article does not use the Reference Frame, simply because it's not used in any common rotation tasks.

Rotation Direction Clarified

Rotation Direction can be either positive or negative around each axis, below are two ways to visualize them.

  • Point your arm straight out from with your thumb up. your hand is the positive end of the axis, and your shoulder the negative
    • a positive value will turn your thumb clockwise(CW), just like the hands on a clock if you are reading the time
    • a negative value will turn your thumb counter-clockwise(CCW), opposite of the way the hands on a clock move
  • Imagine an arrow with your head (the positive end) at the top, and your feet (the negative end) at the bottom
    • a positive value will turn you to your left(L)
    • a negative value will turn you to your right(R)

Preferred Functions

The following functions work in all scenarios. Other functions contain bugs in some situations, and not others. You can use them, but maximum compatibility will be obtained with these.

Representing Rotations

  • There are three simple programmatically useful ways to represent rotations in LSL
    • as a vector of degrees (which most people can easily read or write)
    • as a vector of radians (which are understood by functions like llTargetOmega)
    • as a rotation quaternion (which are understood by functions that set rotations)

Creating and Converting Rotations

<lsl> //-- To create a vector of 15 degrees clockwise around the Z axis vector vDegLeft15z = <15.0, 0.0, 0.0>;

//-- always use a decimal point in rotation or vector elements,
//-- or the compiler will insert code to convert to floating point numbers
//-- To convert that to radians (needed for some functions, and to convert to rotation quaternion)

vector vRadLeft15z = vDegLeft15z * DEG_TO_RAD;

//-- or..

vector vRadLeft15z = <15.0, 0.0, 0.0> * DEG_TO_RAD;

//-- to convert the radians to a rotation quaternion

rotation vRotLeft15z = llEuler2Rot( vRadLeft15z );

//-- or directly from the degrees...

rotation vRotLeft15z = llEuler2Rot( <15.0, 0.0, 0.0> * DEG_TO_RAD );

//-- Say you have a rotation quaternion (vRot2Convert), and want to get radians or degrees notation for it...

vector vRadConverted = llRot2Euler( vRot2Convert ); vector vDegConverted = vRadConverted * RAD_TO_DEG;

//-- or...
vector vDegConverted = llRot2Euler( vRot2Convert ) * RAD_TO_DEG;</lsl>

Reversing a Rotations Direction

  • sometimes you want to get the rotation to spin the opposite way here are three ways to do that

<lsl>vector vDegLeft15z = <0.0, 0.0, 15.0>; //-- this is the original value

//-- change the sign on all the non-zero x, y, z elements, good for rotations that won't change

vector vDegRight15z = <0.0, 0.0, -15.0>;

//-- Multiply the vector value by -1

vector vDegRight15z = vDegLeft15z * -1; //-- also works for vector radians

//-- Divide ZERO_ROTATION by the rotation quaternion
rotation vRotRight15z = (ZERO_ROTATION / vRotLeft15z); //-- always parenthesize your reversal</lsl>

Rotation Math

  • Adding or Subtracting rotations are achieved with the "*" and "/" operators respectively.
    • The order that you add rotation in changes the rotation frame that the operation works on (detailed below)
    • Do not use the "/" operator for anything but rotation reversal, as it's rules are slightly in the behavior frame and can give unexpected results
  • To rotate in the Self Frame (prim's own axis):
    • (vRotAmount2ChangeBy * vRotCurrentLocal)
  • To rotate in the Local Frame:
    • (vRotCurrentLocal * vRotAmount2ChangeBy)
  • To rotate a child prim in the Global Frame
    • (vRotCurrentLocal * vRotAmount2ChangeBy * vRotRootLocal)

Finding a Local Point for a Self offset

Let's say you want to know the Local coordinates of a point that is 1 meter in front (positive self x axis) of your object (like one might use for a gun, or product rezzor), no matter how the object is rotated. <lsl> vPosOffset = <1.0, 0.0, 0.0>; //-- the distance and direction from your objects center to the point we want, in local frame. vPosLocal = (vPosOffset * llGetLocalRot()) + llGetPos(); //-- multiply by the local rotation and add the local position</lsl>

  • For a child prim needing a global point, treat the point calculated above from the child as a self offset to the root and repeat the steps using that point and the values for the root.
IMPOTANT NOTE: the llRez* functions always use the avatars position and rotation for the root when used in attachments. make sure you use functions that get the avatar values when rezzing from attachments.

Rotating a Prim Around a Point

  • Being rewritten

Comments

Feel free to leave me a note on my User Talk page.