Jump to content

Fighting with LSL's Rotations (and losing badly)


Frankie Rockett
 Share

You are about to reply to a thread that has been inactive for 1612 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hi

Try as I might I have to admit that I will never understand the maths or the geometry behind anything other than 'degrees' of rotation along three axis in SL. I say this upfront in case anyone tries to explain underlaying concepts to me! Keep it simple (because I'm) stupid (when it comes to this stuff).

I have a script rezzing a flattened square prim with an image on it's front-most face that rez's against a wall I have provided. I have it working so it functions no matter which compass point the wall faces. However what I'd like to do is have it's orientation on one axis randomly oriented when it rezs. Imageine a poster that might be upside down, sideways, or any other of the 360 available angles. So the bones of what I'm working with is here:

Quote

        rotation relativeRot = <0.707107, 0.707107, 0.707107, 0.707107>;
        vector myPos = llGetPos();
        rotation myRot = llGetRot();
        vector rezPos = myPos+relativePosOffset*myRot;
        vector rezVel = relativeVel*myRot;
        rotation rezRot = relativeRot*myRot;
 
        llRezObject(object, rezPos, rezVel, rezRot, startParam);

It's the object's own Z axis I need to spin. Everything I try seems to cause complex interactions and rotate the prim on more than one axis. Take the first line for example. If I change any of the 4 parameters, the object will rez skewed on at least two axis. I have spent hour (and hours...) on this and would be so grateful to know at what point I can inject values between 1 & 360 to have the object still flat against the wall but rotated some - like clock hands for example.

Thank you!

 

Edited by Frankie Rockett
Link to comment
Share on other sites

The easiest way to use rotations is to... not. More specifically, life gets easier when you don't touch quaternions (the "rotation" type, with 4 values) directly.

Instead, you should define a rotation in normal XYZ degrees, like so:

vector relative_rot = <0, 0, 45> * DEG_TO_RAD;
// "DEG_TO_RAD" is a conversion from "degrees to radians."
// Rotations use radians, but don't think about it.
// Just do the conversion and forget about it.

So, now you have relative_rot in a format that can be given to llEuler2Rot, which converts the XYZ rotation into a proper rotation.

vector relative_rot = <0, 0, 45> * DEG_TO_RAD;
rotation relative_r = llEuler2Rot(relative_rot);

Now you have relative_r which you can use to correctly apply a 45-degree rotation around the Z axis.

 

Similarly, if you want to adjust some object's existing rotation, you can do the conversion in the opposite direction:

rotation object_r = llGetRot();
vector object_rot = llRot2Euler(object_r) * RAD_TO_DEG;

object_rot.z += 45; // Add 45 degrees to the Z rotation.

llSetRot(llEuler2Rot(object_rot * DEG_TO_RAD));

This doesn't directly answer your question, but hopefully this can guide you towards easier rotations. If not, I can get back to you later tomorrow.

  • Thanks 2
Link to comment
Share on other sites

working directly in quaternions/rotations is not as easily readable as are radians/degrees. We do have to know how to do quaternion math. Which is dissimilar to arithmetic math which we can use with degrees/radians using llEuler2Rot() and llRot2Euler()

if you do want to get a better understanding of quaternions then can begin with wikipedia here: https://en.wikipedia.org/wiki/Quaternion

my general suggestion with these kinds of problems is to write the code using Euler and when working, llSay the rotation values to the chat.  Then copy pasta the values into the code where appropriate.  (a side benefit being a reduction in Euler/Rot function calls)

after a while, seeing quaternion values that do work as intended, can help us to better understand what we read about quaternions on wikis and tutorials

  • Thanks 1
Link to comment
Share on other sites

7 hours ago, Frankie Rockett said:

t's the object's own Z axis I need to spin. Everything I try seems to cause complex interactions and rotate the prim on more than one axis. Take the first line for example. If I change any of the 4 parameters, the object will rez skewed on at least two axis.

The first three parts of the quarternion are the amounts of rotation on the X, Y and Z axis, so a 90 degree rotation on the Z axis would have zero in the first two sections, and then 0.707107 in the Z section,. but it must then have 0.707107 in the fourth part, which is the total amount of rotation on the object.

Try altering your script to have radian values in just the 3rd and 4th positions of the quarternion, remembering that the values are going to be within the range -1.0 to 1.0, and you should be able to do what you want.

  • Thanks 1
Link to comment
Share on other sites

Hi Wulfie

I tried my (clearly faulty) implementation of your very clear instructions, with the resukt that the rezzor itself started to randomly rotate, rather than the thing rezzed. Here's the code.
 

Quote

 

string object = "Splat Black  L 1"; // Name of object in inventory
vector relativePosOffset = <-6.0, 0.0, 2.5>; // "Forward" and a little "above" this prim
vector relativeVel = <0.0, 0.0, 0.0>; // Traveling in this prim's "forward" direction
rotation relativeRot = <0.707107, 0.707107, 0.707107, 0.707107>;

integer startParam = 10;


integer RandInt(integer lower, integer higher) {
    integer Range = higher - lower;
    integer Result = llFloor(llFrand(Range + 1)) + lower;
    return Result;
}


default
{
    state_entry()
    {
    }

   touch_start(integer a)
    {
        vector myPos = llGetPos();
        rotation myRot = llGetRot();
        
// Edits
        vector object_rot = llRot2Euler(myRot) * RAD_TO_DEG;
        integer n1 = RandInt(1, 360);
        object_rot.z += n1;
        llSetRot(llEuler2Rot(object_rot * DEG_TO_RAD));
// End edits
    
        vector rezPos = myPos+relativePosOffset*myRot;
        vector rezVel = relativeVel*myRot;
        rotation rezRot = relativeRot*myRot;
 
        llRezObject(object, rezPos, rezVel, rezRot, startParam);
    }
}

 

My best guess was to try to change the definition of rezRot by assigning rotation rezRot = llSetRot(llEuler2Rot(object_rot * DEG_TO_RAD)); but that's a syntax error! can you see where I'm going wrong? Oh - the lines of yours I took and modified for this script's variable names is enclosed in the section marked 'Edit's'.

 

Profaitchikenz - thank you for your suggestion too, which I had to try because it seemed so deliciously simple. No joy. So I found that changing:
rotation relativeRot = <0.707107, 0.707107, 0.707107, 0.707107>;
to
rotation relativeRot = <0.0 0.707107, 0.0, 0.707107>;
yields functionally identical results in that it rezes the 'picture prim' in the correct initial orientation (face X 'forwards') so I naturally assumed that changing the 2nd parameter would change the 'spin' of the image as required. No dice. Keeping within the 0 - 1.0 range as you said, I tried for example <0.0,  0.1,  0.0,  0.707107>; which made it rotate on the wrong axis. Remembering your comment about making the 4th parameter the same. I went with <0.0,  0.1,  0.0 , 0.1>; - all good. Except when I tried other values like <0.0,  0.4,  0.0 , 0.4>; and <0.0,  0.9,  0.0 , 0.9>; - no rotation occured at all. The various changes of value had no effect on rotation of the rezzed item. 'Clearly shome mishtake', as folk start saying nearer Christmas. Do you have a hair of the dog for me?!

Thank you all.

 

 

Edited by Frankie Rockett
Code comment correction
Link to comment
Share on other sites

You won't get very far just throwing in numbers like that. Make up some vectors with degrees in, convert them to rots and check how the numbers go. Quick snippet;

Vector angle;
rotation rot;

convert()
{
  angle = <0.0, 90.0, 0.0>;
    rot = llEuler2Rot(angle*DEG_TO_RAD);
    llWhisper(0, (string) angle + " is " + (string) rot);
    }

Once you know the rotation in degrees you want on the three axes, plug those values into the vector and you'll see what the equivalent rotation is.

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Thank you Everyone!
To Profaitchikenz:
Thank you so much! That is brilliant. I am indebted to you. After a few hccups I realised I had been 'randomising' the wrong parameter. I needed to leave 90 in the second parameter slot and randomise the first, the x parameter. Then it all worked perfectly. Thank you.

A huge Thank you too to Wulfie for fearlessly slashing away the complexity of rotations for me! Education by subtraction has a lot to be said for it - so seriously, thank you Wulfie.

Lastly, thank you to Mollymews for adding all the complexity back in with your background reading! Hahaha! I'm only teasing - thank you.

Cheers to all!

Edited by Frankie Rockett
Total revision of posting.
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1612 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...