This site is in no way affiliated with or endorsed by Linden Labs

Second Life® and Linden Lab® are trademarks or registered trademarks of Linden Research, Inc. All rights reserved. No infringement is intended.
Site Map
RSS Feed from slBuilding.com
 
Make a gift of hope for someone with HIV / AIDS
I recommend Ad Muncher
Blocks ads in all browsers, including Internet Explorer, Firefox, Opera, Google Chrome, Safari, Flock, Netscape, Maxthon and Avant Browser

I use it myself and it does the trick!
DOWNLOAD
Get rid of annoying advertisements!
When you start writing script in Second Life it doesn't take long to hit a problem with rotating objects. Of course, it may be that the items you're building and the script you're writing has no reliance on rotating objects at all, in which case you're blissfully unaware of there being a problem.

But for those of us who ran into object rotation fairly early on in our Second Life scripting "careers", it can be a painful and frustrating experience.

The Problem, and a bit of background

So what's the problem? Let me start by talking about how you rotate objects when you're editing them in Second Life using the Viewer. You have two options:

1) You either hold down the Control key and rotate them by hand, using the visual guides that appear
2) Or you change the X, Y and Z values on the edit object dialog box, which allows you greater precision in your rotations.

Both of these methods work well, but let me talk briefly about the second one on particular. When you enter rotation values into the X, Y and Z fields you specify them in degrees (eg 90 degrees for a quarter of the way around the circle, 180 degrees to flip them around an axis, etc) and the rotations work in the traditional "yaw, pitch and roll" approach that you've probably used elsewhere. So "yaw" rotates an object around the Y axis on the XZ plane for example, and pitch is up and down around the X axis on the YZ plane.

What you're actually doing is using so-called "Euler" rotations, named after Swiss mathematician Leonhard Euler who made significant contributions to mathematics - you may remember him from your school maths lessons.

We've all grown up with so many examples of Euler rotations it's sometimes easy to forget that this is just one way of representing rotations. However there are other ways of skinning this particular cat, and William Hamilton, born about a century after Euler, devised a system that involves expressing rotations as an angle of rotation around a vector. In fact, Hamilton's system - called "quaternions" - is pretty exotic unless you're a mathematician, and might have remained a curiosity confined to mathematics textbooks if it hadn't been for the advent of 3D graphics and computers.

You see, it turns out the Hamilton's quaternions have some interesting advantages over Euler's method when you're working in 3D. These can be summarised as:

1) Avoiding a common problem in Euler rotation called "gimbal lock" that occurs when one or more axis align causing a loss of the frame of reference (don't worry about this unless you want to - it's just background, but take a look at this Wikipedia article if you want to know more)

2) A creeping inaccuracy caused by the imprecision implied by the way Euler rotations are stored and manipulated. Quaternions suffer less from this than Euler-based rotations.

3) The difficulting in calculating interpolated values between two rotations. So for example, if you want to rotate an object smoothly in 3D space from one roation value to another, you need to calculate a number of intervening rotations that you can use to make the rotation smooth. While still not a trivial exercise this is easier (and less resource or processor intentsive as a result) when you're using quaternions.

What this all means - and don't worry if the above three points didn't mean all that much - is that 3D software typically uses quaternions to represent rotation, rather than the "traditional" Euler method that we all know and love.

And Second Life is no different: While they have stuck to the Euler method in the Edit Object box that you access using the Second Life viewer, when it came to LSL script they couldn't help themselves: Any self-respecting 3D software uses quaternions and I'm guessing they felt an overwhelming urge to do the same. And to make things worse, LSL works in radians not degrees, which again is more typical for 3D software but far from intuitive for people who aren't mathematicians or 3D software gurus.

In some ways I think these choices are a shame, because it makes rotations more complicated and less accessible than they should be for us mere mortals, and the advantages of quaternions over the Euler method don't really manifest themselves particularly well in SL. Or at least, that's MHO.

So what does this mean? It means that you either need to understand how quaternions work, and believe me they are far from simple - or you need to find a way to work around them so that you can continue to use Euler rotations in your script. You may not be surprised to hear we're going for the latter approach.

The Solution. Or maybe just "a" solution

Fortunately for us, Linden Labs have built a number of commands and constants into LSL that will make our lives easier. If you've watched the videos you'll know that I proposed a solution based on a "make_quaternion" function, but actually we don't need to go to those lengths. I've since posted an "optimized" version of the source code with the videos that uses the somewhat slicker approach I'm about to describe here.

There are two commands you should be aware of:
1) llEuler2Rot
2) llRot2Euler

and two constants:
1) DEG_TO_RAD
2) RAD_TO_DEG

We'll take a look at each of these in turn.

"llEuler2Rot" could acutally have been called "llEuler2Quaternion" as that's what it does ie it translates an Euler rotation to a quaternion. So you pass it an Euler rotation in a vector and it returns a rotation variable that you can use directly with commands such as llSetRot.

So for example:
Handling Rotations in LSL Script
Copyright © 2007 Ian Monstre  ·  All Rights reserved
rotation rot = llEuler2Rot(<0.1, 0.2, 0.3>);
This converts the Euler rotation of X = 0.1, Y = 0.2 and Z = 0.3 into a quaternion (remember that these values are in radians at the moment - we'll explain how to change that shortly).

You could then use this rotation value directly to rotate the object, for example:
rotation rot = llEuler2Rot(<0.1, 0.2, 0.3>);
llSetRot(rot);
Of course this works the other way around as well: You can use llRot2Euler to convert a quaternion value to an Euler value. Why would you want to do that? Well commands such as "llGetRot()" return a quaternion. If you want to inspect it in your script you might find it easier to do that if the values are Euler values. For example:
vector rot = llRot2Euler(llGetRot());
llSay(0, "The X value is currently set to " + (string)rot.x + " radians");
Now I don't know about you but I don't find it easy working in radians. If you remember from school days, there are 2 PI radians in a circle ie 2 PI radians = 360 degrees. So you can convert radians to degrees by multiplying by 360 and dividing by 2 PI .... but who wants to do that? Thankfully Linden Labs have defined two constants that already have this value, along with its inverse for converting the other way. You use them like this:
rotation rot = llEuler2Rot(<0, 90 * DEG_TO_RAD, 0>);
llSetRot(rot);
This would set your object's rotation to X = 0, Y = 90, Z = 0 exactly as if you have typed those values yourself using the Second Life viewer's object editor.

And of course it works the other way around as well, so you could do this:
vector rot = llRot2Euler(llGetRot());
llSay(0, "The X value is currently set to " + (string)(rot.x * RAD_TO_DEG) + " degrees");
And that's about it. I hope it has made it easier for you to work with rotations in your Second Life scripts.