Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Quaternion question

Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-19-2006 01:13
Okies... I'm confused here, and need some help.

In what I'm working on, I need to get a "local" rotation based on two "global" rotatopn, on the prim I need a local rotation to be relative to, the other an agent.

I do: rotation local_rotation = agent_global_rotation / my_global_rotation;

Assuming that's correct... why is it that when, for instance, my_global_rotation is null-rotated, and agent_global_rotation is close to, but off a tad on X, Y and Z axes from null the above gives me one result, but if my_global_rotation is rotated 180 degrees about Z, and my_global_rotation is also, plus the same offsets as before, local_rotation has slightly different results? I mean, they're the same in that the local rotated prim faces the same way relative to it's root prim, but the numbers look to be inverted from one another.

Can I correct for this? I need to isolate an axis and this difference is making it near impossible, as the result of an llRot2Euler changes depending on the orientation of the root prim.
_____________________
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
10-19-2006 02:17
I can't seem to reproduce what you're seeing.

You may be seeing a rotation <x,y,z,s> sometimes, and sometimes <-x,-y,-z,-s>? Is that what you mean by "inverted"? The two quaternions represent the same rotation of a 3d object, and as far as I can tell, return the same thing from llRot2Euler.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
10-19-2006 06:09
From: Jillian Callahan
Can I correct for this? I need to isolate an axis and this difference is making it near impossible, as the result of an llRot2Euler changes depending on the orientation of the root prim.

What exactly are you trying to achieve? When it involves rotations then whatever it is, there's usually better ways to go about it than euler conversions (like llRot2Fwd() etc to isolate local rotation axes etc) ... but it's hard to tell without knowing what you are using that 'local angle' thing for ^^;
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-19-2006 09:46
Thank you both for answering - I appreciate! Especially since I posted that in the wee hours and it's a mess >.<

What I need to do is this: Check to make sure a given rotation about an axis is within limits, and if it's outside those limits lock it to the limit.

What I am trying to do is look at each element of the euler representation and limit it, then convert back to the quaternion. It's ugly and innefficient but I simply don't know another way. Plus, it seems it doen't work. I'm befuddled that after converting the rotation to something "local" (ie, relative to the root prim) that the rotation of the root prim globally makes any difference. But it does.

The X and Y axes seem to change (in the euler). Root prim facing east (0 on the Z) the Y axis is a smallish number of radians and the X largish. Root prim facing west (180 on the z) and the X gets smallish and the Y largish. I hope that makes sense.

Can anyone tach me a better way of limiting range of motion?
_____________________
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
10-19-2006 11:30
Trying to do any math or manipulations with the individual elements of an Euler rotation is asking for trouble. Euler rotations aren't continuous where you expect them to be, which is why you saw radical differences in Euler rotation for small differences in object orientation.

From: someone
What I need to do is this: Check to make sure a given rotation about an axis is within limits, and if it's outside those limits lock it to the limit.


So are you saying you have a rotation, and you know it's about a certain axis, and the only thing that varies is the number of degrees to rotate?

You can do some stuff like this:

CODE

rotation rot; // the rotation to test
vector axis = llRot2Axis(rot);
float angle = llRot2Angle(rot);

if (axis != the axis in question) // pseudocode, don't actually use != on vectors
complain();
else {
if (angle < LOWER_BOUND)
angle = LOWER_BOUND;
else if (angle > UPPER_BOUND)
angle = UPPER_BOUND;
}

rotation constrained = llAxisAngle2Rot(axis, angle);


That's a little inefficient/imprecise because in cases where the rotation wasn't constrained at all, the conversion to axis/angle and back is unnecessary, and might introduce floating point errors. Then again, it might not... I'm not sure.

If you also want to constrain the axis to within a certain number of degrees from a reference axis:

CODE

vector REFERENCE_AXIS; // set this to whatever
rotation rot; // the rotation to test

vector rotAxis = llRot2Axis(rot);
float rotAngle = llRot2Angle(rot);


rot deviance = llRotBetween(rotAxis, REFERENCE_AXIS); // calculate a rotation to get from the current rotation's axis to the desired axis
float devianceAngle = llRot2Axis(deviance);
vector devianceAxis = llRot2Angle(deviance);

// do something similar to above to constrain the devianceAngle and then somehow modify the rotAxis as needed... I'm not clear on this part



Yeah. That problem's a fair amount more difficult, so I hope it's not what you're trying to do ;)
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-19-2006 11:40
From: Lex Neva
That problem's a fair amount more difficult, so I hope it's not what you're trying to do ;)
Of course that's exactly what I am trying to do :D
_____________________
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
10-19-2006 12:49
llAngleBetween?
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-19-2006 12:53
From: Seifert Surface
llAngleBetween?
I can figure if I'm out-of-bounds with that, but I can't figure how I'd then retreat the rotation to the closest edge of bounds.
_____________________
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
10-19-2006 15:58
CODE

float max_angle = 0.5; //in radians
rotation cap_rotation(rotation input)
{
float angle = llRot2Angle(input); //if this returns angles in [0, 2PI) rather than angles in [-PI, PI) then you need to fix it
if(llFabs(angle) <= max_angle)
{
return input;
}
else
{
if(angle >= 0)
return llAxisAngle2Rot(llRot2Axis(input), max_angle);
else
return llAxisAngle2Rot(llRot2Axis(input), -max_angle);
}
}



_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-19-2006 18:09
From: Seifert Surface
CODE

float max_angle = 0.5; //in radians
rotation cap_rotation(rotation input)
{
float angle = llRot2Angle(input); //if this returns angles in [0, 2PI) rather than angles in [-PI, PI) then you need to fix it
if(llFabs(angle) <= max_angle)
{
return input;
}
else
{
if(angle >= 0)
return llAxisAngle2Rot(llRot2Axis(input), max_angle);
else
return llAxisAngle2Rot(llRot2Axis(input), -max_angle);
}
}
Ooohhh... Thank you Seifert!

Ok, if I understand that right; it will clamp any deviation from null rotation over 0.5 radians, yes? Giving me a cone-shaped boundary?

How might one go about, say, elongating the cone? Like, I've more room to twist about the Z axis than I do the X or Y.

EDIT:
Now that I've tried it I know I totally don't get it. Doesn't do what I think it does.
_____________________
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
10-20-2006 03:46
From: Jillian Callahan
Ok, if I understand that right; it will clamp any deviation from null rotation over 0.5 radians, yes? Giving me a cone-shaped boundary?
It should clamp rotation to 0.5 radians... but I've not been in world to test it. I'm not sure what you mean by cone shaped boundary...boundary of what? That [0 to 2Pi) thing might be messing it up too.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-20-2006 06:28
From: Seifert Surface
It should clamp rotation to 0.5 radians... but I've not been in world to test it. I'm not sure what you mean by cone shaped boundary...boundary of what? That [0 to 2Pi) thing might be messing it up too.
Cone shaped, as in an 0.5 radian cone - the angle off of null? *looks hopeful*

I added a quick check and it's -pi to pi. Thing is, it doesn't seem to clamp the rotation at all. No discernable effect :(
_____________________
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
10-20-2006 09:41
From: Jillian Callahan
Cone shaped, as in an 0.5 radian cone - the angle off of null? *looks hopeful*

I added a quick check and it's -pi to pi. Thing is, it doesn't seem to clamp the rotation at all. No discernable effect :(


Ah, well there's no "distance from the origin" if you're talking about a rotation, so I think the right thing to say would be "circle" rather than cone. Then again, the space you're really moving in is unit quaternions rather than 3d space, so its a bit uglier.

I'll jump in in a bit and see what that code is doing.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
10-20-2006 11:00
Okay, now I'm kind of confused. Jillian, can you give a more detailed description of what you're trying to do?
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-20-2006 13:33
Ok, I'm sorry that I'm not doing well describing this. I want to check some arbatrary rotation and make sure that rotation keeps an object "pointing" in a specific range, as in the image. Sort of a set of hard stops on yaw, and hard stops on pitch. I'm not concerned about roll.
_____________________
Kage Seraph
I Dig Giant Mecha
Join date: 3 Nov 2004
Posts: 513
10-20-2006 13:41
This would be a pretty sweet application as concerns nose or tail turrets for the CCC. IIRC, Rickard Roentgen was doing a bit of brainwork on angle-constrained turrets for a personal combat craft awhile back. The main benefit was so that the pilot could not accidentally shoot herself at the extremes of the turrets' rotations. Maybe check with Rickard?
_____________________
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
10-20-2006 16:02
Ok that's weird. It seems that when sitting on something, the orientation of the prim you're sitting on has an effect on your avatar's rotation returned from llDetectedRot and the like. Presumably this is something to do with the avatar being in coordinates relative to the prim you're sitting on. I'll send you a thing to demo it Jillian.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
10-20-2006 17:29
Have you tried seeing if the values returned are different when you are in mouselook? When you sit you become linked with the prim the script is in. An avatar can only rotate around the z axis unless they are in mouselook. Just some thoughts. Haven't gone online to play with it to see.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-20-2006 17:32
=o.0=

It figures there's some strange thing there with avs on objects.
Time to experiment with alternate info gathering! =^.^=

EDIT:

10,000 thank-yous to everyone, especially Seifert, who's brilliant =^.^=
_____________________
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
10-21-2006 09:55
From: Jillian Callahan

10,000 thank-yous to everyone, especially Seifert, who's brilliant =^.^=


Well come on, don't hold back! I'm curious. I think I actually had to do this for something I wrote awhile back, and I ended up with a kludge: I converted the rotation to an euler, divided the euler by the car's rotation to make it relative, and then messed with the individual axes. Really not what you're supposed to do.
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
10-21-2006 10:15
From: Lex Neva
Well come on, don't hold back! I'm curious. I think I actually had to do this for something I wrote awhile back, and I ended up with a kludge: I converted the rotation to an euler, divided the euler by the car's rotation to make it relative, and then messed with the individual axes. Really not what you're supposed to do.
I'm not holding back, I'm still workin' on it.

Using the Euler elements isn't working. I rotate them to be "local" and ... they behave diffeently depending on the orientation of the root prim. Seifert sent me an object that demonstrates how llDetectedRot() behaves quite differetnly when looking at an avatar sitting on a prim, and this is the root of the problem.

At the moment I'm looking at sort-of filtering the strange behavior by using llRot2Fwd(), checking to see if that vector is in-bounds and modifying the vector to be in-bounds if not, then using llRotBetween() to convert the result back to a local rotation.

It's not 100% successful. Mostly becasue I'm not 100% sure how to rotate the vector down to the hard-stop boundary accurately...
_____________________