Difference between revisions of "User:Pedro Oval/Calculate rotation for pointing in a direction"

From Second Life Wiki
Jump to navigation Jump to search
(Expand text, add authorship comment)
(Change formulation to a shorter one; add PointAtViewup2Rot)
Line 1: Line 1:
Here are two functions that, given a vector to point at, return the rotation that corresponds to that vector.
Here are two functions that, given a vector to point at, return the rotation that corresponds to that vector.


The first function, <code>PointAt2Rot</code>, makes the forward (X) vector point exactly in that direction, while keeping the up (Z) vector pointing "as up as possible". It is similar to what llLookAt does, except that the vector that points to the target is X (forward) instead of Z (up), and the result is a rotation, not a continuously updating state of pointing in the given direction.
One of the functions, <code>PointAt2Rot</code>, makes the forward (X) vector point exactly in that direction, while keeping the up (Z) vector pointing "as up as possible". It is similar to what llLookAt does, except that the vector that points to the target is X (forward) instead of Z (up), and the result is a rotation, not a continuously updating state of pointing in the given direction.


The second function, <code>PointAtHoriz2Rot</code>, points to the horizontal that is closest to the given vector, while the up vector points exactly up. It is useful if the final resulting rotation must be horizontal.
The other function, <code>PointAtHoriz2Rot</code>, points to the horizontal that is closest to the given vector, while the up vector points exactly up. It is useful if the final resulting rotation must be horizontal.


Note that both functions have trouble handling the case where the target is directly above or below the source, and in that case the resulting rotation might be wrong.
<lsl>
// Written by Pedro Oval, 2011-01-11
 
rotation PointAtHoriz2Rot(vector target)
{
    // Find the Z rotation:
    return llRotBetween(<1., 0., 0.>, <target.x, target.y, 0.>);
}
 
rotation PointAt2Rot(vector target)
{
    // Find the Z rotation:
    rotation r = PointAtHoriz2Rot(target);
    // Find the Y rotation and multiply it with the Z one:
    return llRotBetween(<1., 0., 0.>, target/r) * r;
}
</lsl>
 
The following is a version of <code>llPointAt2Rot</code> that allows a viewup vector (the vector that determines the tilting). Remember that it's in world coordinates, therefore if it's wanted to be in the prim's local coordinates (which is very likely), it must first be converted via dividing by [[llGetRot]]:


<lsl>
<lsl>
// Written by Pedro Oval, 2011-01-08
// Written by Pedro Oval, 2011-01-08


rotation PointAt2Rot(vector target)
rotation PointAtViewup2Rot(vector target, vector viewup)
{
{
     vector fwd = llVecNorm(target);
     vector fwd = llVecNorm(target);
     vector left = llVecNorm(<0., 0., 1.> % fwd);
     vector left = llVecNorm(viewup % target);
     vector up = fwd % left;
     vector up = fwd % left;
    return llAxes2Rot(fwd, left, up);
}
rotation PointAtHoriz2Rot(vector target)
{
    vector up = <0., 0., 1.>;
    vector left = llVecNorm(up % target);
    vector fwd = left % up;
     return llAxes2Rot(fwd, left, up);
     return llAxes2Rot(fwd, left, up);
}
}
</lsl>
</lsl>

Revision as of 05:27, 11 January 2011

Here are two functions that, given a vector to point at, return the rotation that corresponds to that vector.

One of the functions, PointAt2Rot, makes the forward (X) vector point exactly in that direction, while keeping the up (Z) vector pointing "as up as possible". It is similar to what llLookAt does, except that the vector that points to the target is X (forward) instead of Z (up), and the result is a rotation, not a continuously updating state of pointing in the given direction.

The other function, PointAtHoriz2Rot, points to the horizontal that is closest to the given vector, while the up vector points exactly up. It is useful if the final resulting rotation must be horizontal.

<lsl> // Written by Pedro Oval, 2011-01-11

rotation PointAtHoriz2Rot(vector target) {

   // Find the Z rotation:
   return llRotBetween(<1., 0., 0.>, <target.x, target.y, 0.>);

}

rotation PointAt2Rot(vector target) {

   // Find the Z rotation:
   rotation r = PointAtHoriz2Rot(target);
   // Find the Y rotation and multiply it with the Z one:
   return llRotBetween(<1., 0., 0.>, target/r) * r;

} </lsl>

The following is a version of llPointAt2Rot that allows a viewup vector (the vector that determines the tilting). Remember that it's in world coordinates, therefore if it's wanted to be in the prim's local coordinates (which is very likely), it must first be converted via dividing by llGetRot:

<lsl> // Written by Pedro Oval, 2011-01-08

rotation PointAtViewup2Rot(vector target, vector viewup) {

   vector fwd = llVecNorm(target);
   vector left = llVecNorm(viewup % target);
   vector up = fwd % left;
   return llAxes2Rot(fwd, left, up);

} </lsl>