Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Trying to understand rotation

Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-28-2009 11:08
ie, "V / R" and "V * (ZERO_ROTATION/R)" are different operations?
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
03-28-2009 13:41
I'm always a bit confused by, and would appreciate guidance with, the rotation rot bit of llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param).

I understand how to rez things at llGetPos()+<1.0,0.0,0.0>*llGetRot() -- I don't mean that part -- but I don't really understand what rotation rot does.

If I've got an object, when it's the right way up, that appears (because of the odd positioning of its root prim) to be rotated at <90,0.0, 90.0> when I look at it in the edit window, and which rezzes like that when I take it out of my inventory, do I want to rez it at ZERO_ROTATION -- i.e. don't mess with how it's rotated anyway -- or at llEulerToRot(<90,0.0, 90.0>*DEG_TO_RAD)?

And what do I do if I want to specify either that it's to rez facing North (no matter which way the rezzer is pointing) OR that I want it always to rez at right-angles to the rezzer?

What I normally do is make it rez where I want it -- because I understand that bit -- at ZERO_ROTATION and then use the on_rez event to turn it round so it's the right way up and facing how I want it, but I'm sure there's a better way to do this.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
03-28-2009 16:02
From: Argent Stonecutter
ie, "V / R" and "V * (ZERO_ROTATION/R)" are different operations?

No. They are the same.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
03-28-2009 16:08
From: Innula Zenovka
I'm always a bit confused by, and would appreciate guidance with, the rotation rot bit of llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param).

I understand how to rez things at llGetPos()+<1.0,0.0,0.0>*llGetRot() -- I don't mean that part -- but I don't really understand what rotation rot does.

If I've got an object, when it's the right way up, that appears (because of the odd positioning of its root prim) to be rotated at <90,0.0, 90.0> when I look at it in the edit window, and which rezzes like that when I take it out of my inventory, do I want to rez it at ZERO_ROTATION -- i.e. don't mess with how it's rotated anyway -- or at llEulerToRot(<90,0.0, 90.0>*DEG_TO_RAD)?

And what do I do if I want to specify either that it's to rez facing North (no matter which way the rezzer is pointing) OR that I want it always to rez at right-angles to the rezzer?

What I normally do is make it rez where I want it -- because I understand that bit -- at ZERO_ROTATION and then use the on_rez event to turn it round so it's the right way up and facing how I want it, but I'm sure there's a better way to do this.

The function takes a "rotation" that orients the rezzed object relative to the global coordinate system. That means if you use ZERO_ROTATION, the rezzed object's x, y, and z axes will be aligned with those of the region (x points east, y points north, and z points up). If you wanted to rez it such that it is rotated 90 degrees about the global z-axis from that (so its x-axis points north and its y-axis points west), you'd use a rotation of 'llAxisAngle2Rot(<0,0,1>, PI_BY_TWO)' which is also equal to '<0.0, 0.0, 0.707107, 0.707107>'.

If, on the other hand, you want to express the rotation of the rezzed object in terms of the coordinate system of the rezzing prim, you'd do the same thing, but multiply the rotation by llGetRot(), which transforms a vector or rotation in the system of the prim to one expressed in the global coordinate system. So the two examples I gave above would instead be 'ZERO_ROTATION*llGetRot()' which is also just 'llGetRot()', and 'llAxisAngle2Rot(<0,0,1>, PI_BY_TWO)*llGetRot()'.
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
03-28-2009 17:44
From: Hewee Zetkin
The function takes a "rotation" that orients the rezzed object relative to the global coordinate system. That means if you use ZERO_ROTATION, the rezzed object's x, y, and z axes will be aligned with those of the region (x points east, y points north, and z points up). If you wanted to rez it such that it is rotated 90 degrees about the global z-axis from that (so its x-axis points north and its y-axis points west), you'd use a rotation of 'llAxisAngle2Rot(<0,0,1>, PI_BY_TWO)' which is also equal to '<0.0, 0.0, 0.707107, 0.707107>'.

If, on the other hand, you want to express the rotation of the rezzed object in terms of the coordinate system of the rezzing prim, you'd do the same thing, but multiply the rotation by llGetRot(), which transforms a vector or rotation in the system of the prim to one expressed in the global coordinate system. So the two examples I gave above would instead be 'ZERO_ROTATION*llGetRot()' which is also just 'llGetRot()', and 'llAxisAngle2Rot(<0,0,1>, PI_BY_TWO)*llGetRot()'.
Thanks so much for the clear explanation and examples. I am going to bookmark this for future reference when next I get confused by this.

One final question about this, if I may. When you say, "the rezzed object's x, y, and z axes," does this mean its local axes (the arrows I see in local ruler mode) ? I get really confused when the rezzed object's root prim is not at <0,0,0>.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
03-29-2009 00:48
From: Argent Stonecutter
ie, "V / R" and "V * (ZERO_ROTATION/R)" are different operations?

sorry I screwed it up, it only fails in local rotation, not global rotation, previous posts will be deleted for reader clarity

R = arc to change by
V = global rotation

R / V != (ZERO_ROTATION / R) * V
R / V shouldn't be used for local rotation,
use (ZERO_ROTATION / R) * V
or R.s *= -1; R * V
to reverse a rotation for local relevant results

V * R applies R around the global axis
R * V applies R around the local axis

demonstration script
CODE

rotation gRotArc;

default{
state_entry(){
gRotArc = llEuler2Rot( <0.0, 0.0, PI_BY_TWO> );
}

touch_start( integer vIntNull ){
rotation vRotTemp = llGetRot();
llOwnerSay( "Prim is at " + (string)(llRot2Euler( vRotTemp ) * RAD_TO_DEG) );

llOwnerSay( "Global Rotations" );
llOwnerSay( (string)(vRotTemp / gRotArc) + " = Current Rotation / 90DegZ" );
llOwnerSay( (string)(vRotTemp * (ZERO_ROTATION / gRotArc)) + " = Current Rotation * (ZERO_ROTATION / 90DegZ)" );
gRotArc.s *= -1;
llOwnerSay( (string)(vRotTemp * gRotArc) + " = CurrentRotation * 90DegZ(reversed by -.s)" );
gRotArc.s *= -1;

llOwnerSay( "Local Rotations" );
llOwnerSay( (string)(gRotArc / vRotTemp) + " = 90DegZ / Current Rotation" );
llOwnerSay( (string)((ZERO_ROTATION / gRotArc) * vRotTemp) + " = (ZERO_ROTATION / 90DegZ) * Current Rotation" );
gRotArc.s *= -1;
llOwnerSay( (string)(gRotArc * vRotTemp) + " = 90DegZ(reversed by -.s) * CurrentRotation" );
gRotArc.s *= -1;
}
}

results:
//-- notice dropped sign in first instance, and reversed signs in other two, reverse is equivalent for LSL application, missing is not
Prim is at <-0.00000, 0.00000, -0.00000>
Local Rotations
<0.00000, 0.00000, 0.70711, 0.70711> = 90DegZ / Current Rotation
<0.00000, 0.00000, -0.70711, 0.70711> = (ZERO_ROTATION / 90DegZ) * Current Rotation
<0.00000, 0.00000, 0.70711, -0.70711> = 90DegZ(reversed by -.s) * CurrentRotation
[...]

//-- again signs differ, inverse is equivalent, mismatched is not
Prim is at <45.00000, 0.00000, -0.00000>
Local Rotations
<-0.27060, 0.27060, 0.65328, 0.65328> = 90DegZ / Current Rotation
<0.27060, 0.27060, -0.65328, 0.65328> = (ZERO_ROTATION / 90DegZ) * Current Rotation
<-0.27060, -0.27060, 0.65328, -0.65328> = 90DegZ(reversed by -.s) * CurrentRotation
[...]

//-- not only is the signage different, but the x and y are flipped
Prim is at <45.00000, 0.00000, 45.00000>
Local Rotations
<-0.14645, 0.35355, 0.35355, 0.85355> = 90DegZ / Current Rotation
<0.35355, 0.14645, -0.35355, 0.85355> = (ZERO_ROTATION / 90DegZ) * Current Rotation
<-0.35355, -0.14645, 0.35355, -0.85355> = 90DegZ(reversed by -.s) * CurrentRotation
Global Rotations
<0.14645, -0.35355, -0.35355, 0.85355> = Current Rotation / 90DegZ
<0.14645, -0.35355, -0.35355, 0.85355> = Current Rotation * (ZERO_ROTATION / 90DegZ)
<-0.14645, 0.35355, 0.35355, -0.85355> = CurrentRotation * 90DegZ(reversed by -.s)
//-- no difference for global rotations

ETA: does anyone know what action is being accomplished in that case (R / V)? It really twists my brain and I'm sure there's a use for it... what I don't know.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-29-2009 06:36
From: Void Singer
sorry I screwed it up, it only fails in local rotation, not global rotation, previous posts will be deleted for reader clarity

R = arc to change by
V = global rotation
In my question, V is a vector. :eek:
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
03-29-2009 11:23
From: Innula Zenovka
One final question about this, if I may. When you say, "the rezzed object's x, y, and z axes," does this mean its local axes (the arrows I see in local ruler mode) ? I get really confused when the rezzed object's root prim is not at <0,0,0>.

Yes. Change to local in the edit window and you will see the axes of the prim or object you have selected. The object's axes/rotation is identical to that of its root prim (just like position).
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
03-29-2009 12:44
From: Argent Stonecutter
In my question, V is a vector. :eek:

heh I wondered what v stood for in your example, all I could think was variable


you know... I've NEVER tried to rotate a vector that way, I've no clue what it might do.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Jack Abraham
Lantern By Day
Join date: 11 Apr 2008
Posts: 113
03-30-2009 10:01
OK, as usual I seem to have asked a rotation related question poorly, and led people off on a tangent.

As an example problem: have two points. I want to rez an object such that it's X-axis is parallel to a line between point A and point B in the XY plane, but ignores any vertical offset.

I'm sure several of you can give me a solution in no time. What I'm missing is any understanding of *why* that solution works. I really hate using black boxes.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
03-30-2009 11:19
From: Jack Abraham
OK, as usual I seem to have asked a rotation related question poorly, and led people off on a tangent.

As an example problem: have two points. I want to rez an object such that it's X-axis is parallel to a line between point A and point B in the XY plane, but ignores any vertical offset.

I'm sure several of you can give me a solution in no time. What I'm missing is any understanding of *why* that solution works. I really hate using black boxes.


Well, you want the object's z-axis to point upward (along the world's z-axis) then, and all you need is to rotate the object about that z-axis until its x-axis points in the same horizontal direction as your input vector. Since your input vector may not be horizontal, it might be easier to think of aligning the y-axis such that it is orthogonal to both the vector and the z-axis. A handy way to do that is to take the cross product (% operator on vectors) of the vectors to which you want an orthogonal one (normalizing the result with llVecNorm() to get a unit--length 1--vector).

Here is the basic version:

CODE

rotation rotFwdToHeading(vector dir)
{
vector localY = llVecNorm(<0.0, 0.0, 1.0>%dir);
vector localX = localY%<0.0, 0.0, 1.0>; // Already a unit vector
return llAxes2Rot(localX, localY, <0.0, 0.0, 1.0>);
}


Here is a version that is optimized a bit, but completely equivalent:

CODE

rotation rotFwdToHeading(vector dir)
{
vector localY = llVecNorm(<-dir.y, dir.x, 0.0>);
vector localX = <localY.y, -localY.x, 0.0>; // Already a unit vector
return llAxes2Rot(localX, localY, <0.0, 0.0, 1.0>);
}


Here is the same basic logic, but it returns an arbitrary value in the special case that the input vector is zero or vertical, since we might get a math error in that case:

CODE

rotation rotFwdToHeading(vector dir)
{
if (llVecMag(dir) < 0.001)
{
return ZERO_ROTATION;
}

dir = llVecNorm(dir);
if (llFabs(dir.z) > 0.999)
{
return ZERO_ROTATION;
}

vector localY = llVecNorm(<-dir.y, dir.x, 0.0>);
vector localX = <localY.y, -localY.x, 0.0>; // Already a unit vector
return llAxes2Rot(localX, localY, <0.0, 0.0, 1.0>);
}


There are other equivalent ways to do this. I'm sure someone'll probably be thinking of a llRotBetween() implementation, so here it is:

CODE

rotation rotFwdToHeading(vector dir)
{
return llRotBetween(<1.0, 0.0, 0.0>, llVecNorm(<dir.x, dir.y, 0.0>));
}


And here's one with a little trig for good measure:

CODE

rotation rotFwdToHeading(vector dir)
{
return llAxisAngle2Rot(<0.0, 0.0, 1.0>, llAtan2(dir.y, dir.x));
}


So take your pick, and if not even one of those makes sense to you, be sure to post a follow-up question outlining your area of confusion. Have fun! :)
Jack Abraham
Lantern By Day
Join date: 11 Apr 2008
Posts: 113
03-30-2009 13:22
Thanks, Hewee. You'd actually given me the answer to this problem before, but this time I understand why it works. Hopefully that means there's something less I'll have to bug you about in the future. I appreciate the lesson!
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
03-31-2009 07:41
From: SuezanneC Baskerville
A discussion of the forum's img posting condition is off topic and in the wrong forum.

.
Good point.

I am totally AGAINST the new ADULT CONTENT BULLSHIT...
_____________________
So many monkeys, so little Shakespeare.
1 2