Script Function: llRotByDegrees
|
|
Oz Spade
ReadsNoPostLongerThanHand
Join date: 23 Sep 2003
Posts: 2,708
|
12-06-2005 16:36
An idea to simplify rotating prims via script without having to do extra math with llRot2Euler and such is to have a llRotByDegrees(x,y,z) function, which would basicly go along side the current Edit menu functionality.
Benefits: - Easier for new/non-advanced scripters to rotate prims. - Saves memory/line usage for anyone by elimating extra math/functions. - Cross functionality that makes sense (using degrees both in edit menu and in scripting makes more sense). - Simplifies the mind and eases the soul.
Example: llRotByDegrees(3.50, 0.0, 180);
_____________________
"Don't anticipate outcome," the man said. "Await the unfolding of events. Remain in the moment." - Konrad
|
|
Nathan Stewart
Registered User
Join date: 2 Feb 2005
Posts: 1,039
|
12-06-2005 16:39
seconded
|
|
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
|
12-06-2005 16:41
Approved. Quaternions are the mindkiller for scripters that don't know/care enough about the math to use them.
_____________________
---
|
|
Ice Brodie
Head of Neo Mobius
Join date: 28 May 2004
Posts: 434
|
12-06-2005 16:43
My work on rotations is just... well, Oz's idea here, only in more code, this could be implimented (as an LSL built in function, but code is listed here for reference) llRotByDegrees(float x,float y,float z) { llSetRot(llEuler2Rot(<x,y,z>)*RAD_TO_DEG); }
but that would save a lot of people a lot of frustration, and for people like me who cheat and just use Euler notation, it'd be a simplifiction. LSL isn't designed to be a black art... so why so much cryptic stuff to do simple things like this?
|
|
Candide LeMay
Registered User
Join date: 30 Dec 2004
Posts: 538
|
12-06-2005 17:07
The editor should also use the numbers you've entered. I know that converting rotation from euler to quaternions and back can yield different representations of the same rotation - so that for example <0,180,0> ends up as <180,0,180> - but there's no reason for the editor to not remember that you entered <0,180,0> and display it
|
|
Ben Bacon
Registered User
Join date: 14 Jul 2005
Posts: 809
|
12-06-2005 20:25
What are we talking about here - quaternions? radians? < and > around vectors? something else? Oz - you seem to be asking for llRotByDegrees(x,y,z) { llSetRot( llGetRot() * llEuler2Rot(<x, y, z>*DEG_TO_RAD)); } which would suffer from gimbal lock the same as any other Euler based system would. Or you're looking for Ice's suggestion, which is basically a way to avoid < and >, and radians. (BTW, get to know radians - most of us do use Euler angles to set absolute rotations, but we tend to use radians where we can). I've seen code that has "<0, 180, 0>*DEG_TO_RAD" where "<0, PI, 0>" would have worked just as well. I've even seen code that says "<0, 0, 0>*DEG_TO_RAD" which does show a little lack of understanding. Jeff - I agree quats are sanity-slayers for mere mortals, but with llEuler2Rot and llRot2Euler we don't need to know/care about the maths.
|
|
Oz Spade
ReadsNoPostLongerThanHand
Join date: 23 Sep 2003
Posts: 2,708
|
12-06-2005 22:28
Ben, your post has confused me and is exactly the reason I want a simpler way of doing things. All this math and adding and multiplying of other functions... it plays tricks on the brain. My key example stated in my original post is pretty straight forward I thought. I basicly want to be able to edit via script in degrees the same way we do in the Edit window. Gimbal lock can easily be avoided by doing something such as... if(llGetDegrees().x==180){ llRotbyDegrees(<0,0,0>  ; } or some such, if you need to do that. That's alot simpler to understand than using multiplication and all that. Rotations are one of my bigest gripes with LSL currently, it's frustraiting at best. So I'm looking to make it simpler, with one function, thats easy on the mind to understand. And yes I made the mistake of not enclosing my floats with < >, as it should be a vektor type variable in there so you can call them into the function.
_____________________
"Don't anticipate outcome," the man said. "Await the unfolding of events. Remain in the moment." - Konrad
|
|
Ben Bacon
Registered User
Join date: 14 Jul 2005
Posts: 809
|
12-07-2005 01:03
Oz, sorry to add confusion to the pot, but I'm afraid rotations are confusing no matter what techniques are used. As an example - place book on the table in front of you. Lift the back up toward you. Rotate it 90 degrees clockwise (viewint from the top). Now take a second book and perform the same two steps - but in the opposite order. Notice that the books are oriented differently. (This, incidentally, is one of the problems with Eulers - in what order should <0, 90, 90> be performed?) This isn't an LSL, or even an SL, issue - it applies to all 3D environments. The convention on the edit box, and in llEuler2Rot, btw is to apply the z, then the y, then the x - but this is not a universal truth. A side-effect of this is that if the y-axis rotation rotates the x-axis to where the z-axis was - then x and z become equivalent and you lose a degree of freedom - this is gimbal lock and there is no easy solution. Quats solve these problems - with the fairly big downside of not being intuitive to humans at all. However, the computer loves 'em. The computer (and most mathematicians!) also prefer radians to degrees. Even your pocket calculator converts degrees to radians before performing trig operation. Quats and radians are the native rotation form for most modern 3D systems, including SL. And here is the key point: You write the code once - the computer executes it millions of times.The learning curve is shallow enough to justify the run-time efficiency. We need to be reminded that even if we introduce helper functions, the system still has to do all the multiplications. This should keep us on our toes. If we pass a vector of degrees in a link message, and if in each child prim we could call llRotByDegrees, LSL would be hiding from us all the unnecessarily repeated work that the system has to do. When we are forced to multiply by DEG_TO_RAD and call llEuler2Rot in every child prim it reminds us to move that work up to the parent, do it once, and pass a quat through the link message. More efficient = less lag. Hoping you have large hands, Yours - Ben
|
|
Oz Spade
ReadsNoPostLongerThanHand
Join date: 23 Sep 2003
Posts: 2,708
|
12-07-2005 11:06
I don't see why the same methods applied to the Edit menu and rotating prims via Degrees could not be applied to an LSL method either.
With all the complicated calculations SL currently does, I doubt handling this function would be of any real damage.
_____________________
"Don't anticipate outcome," the man said. "Await the unfolding of events. Remain in the moment." - Konrad
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
12-07-2005 12:34
Making it work like the client is a bad idea. The way the client does it is really really bothersome. The clients version works exactly like llSetRot (that is instead of llSetLocalRot). This means that on child prims it behavies very strangly and counter intuitive. The build tools are high on my list of getting changed.
Realisticly i don't see much point, it only saves 19 bytes.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Oz Spade
ReadsNoPostLongerThanHand
Join date: 23 Sep 2003
Posts: 2,708
|
12-07-2005 14:11
Have any other suggestions for simplifying rotations? Or should they remain a difficult and unfriendly concept for most people for ever? 
_____________________
"Don't anticipate outcome," the man said. "Await the unfolding of events. Remain in the moment." - Konrad
|
|
Ben Bacon
Registered User
Join date: 14 Jul 2005
Posts: 809
|
12-08-2005 01:02
Oz, no offense intended, but doctors are willing to learn medicine, engineers are willing to learn engineering and pilots are willing to learn to fly.
For some reason too many developers are not willing to learn their art.
Anyone scripting in a 3d environment should be willing to study up on "difficult and unfriendly" concepts AKA "concepts I haven't learned yet". Once you do you'll discover how easy they actually are to work with.
As far as simplifying rotations is concerned - an age old development philosophy is "make is as simple as it needs to be, but no simpler". Remember, also, that "most people" scripting rotations in LSL probably already are comfortable with radians, and likely were before they even started SL.
|
|
SuezanneC Baskerville
Forums Rock!
Join date: 22 Dec 2003
Posts: 14,229
|
12-09-2005 13:09
From: Candide LeMay The editor should also use the numbers you've entered. I know that converting rotation from euler to quaternions and back can yield different representations of the same rotation - so that for example <0,180,0> ends up as <180,0,180> - but there's no reason for the editor to not remember that you entered <0,180,0> and display it I've suggested this before and was not well treated as a result. I agree wholeheartedly with your suggestion, it is just common sense that it should remember which field you change and display it with just that field changed and the other fields like they were before the change.
_____________________
-
So long to these forums, the vBulletin forums that used to be at forums.secondlife.com. I will miss them.
I can be found on the web by searching for "SuezanneC Baskerville", or go to
http://www.google.com/profiles/suezanne
-
http://lindenlab.tribe.net/ created on 11/19/03.
Members: Ben, Catherine, Colin, Cory, Dan, Doug, Jim, Philip, Phoenix, Richard, Robin, and Ryan
-
|
|
SuezanneC Baskerville
Forums Rock!
Join date: 22 Dec 2003
Posts: 14,229
|
12-09-2005 13:55
There is a perfectly good reason to add "* DEG_TO_RAD" to <0,0,0>, the reason being consistency and clarity. If you or someone else decides to change those values the presence of the conversion value indicates that the values are displayed in degrees although the program will deal with them in radians. When you build surgical tools or airplane controls you can build them in different ways, some ways being easier to understand and less error prone in use. It's better to make tools better even when the tools are being used by professionals. LSL is not used exclusively by professionals. It is used to some extent for fun, for playing with. Failure to make the language as simple and easy to use as possible reduces the pleasure it brings to many people and can be one of the factors that causes a person to drop SL as an activity. Here's my solution to my difficulties in dealing with rotations. This solution slows the script down but for my simple scripts that do things like build giant regular polygons and multiprim mobius strips for a few minutes a year that doesn't make any difference. spinx( float d) { llSetRot( llEuler2Rot( <d*DEG_TO_RAD, 0, 0> ) * llGetRot() ) ; }
spiny( float d) { llSetRot( llEuler2Rot( < 0, d*DEG_TO_RAD, 0> ) * llGetRot() ) ; }
spinz( float d) { llSetRot( llEuler2Rot( < 0, 0, d*DEG_TO_RAD > ) * llGetRot() ) ; } My solution changes only one axis at a time, and changes are relative to the objects current rotation. I find that this enables me to more easily imagine myself as the thing being rotated and come up with the correct sequence and values needed to twist the thing the way it needs to be twisted. The part of this solution that is "mine" is not the part that involves the calculations and rotation functions, those are just straightforward use of the LSL functions. The part that is mine is the acceptance that my brain only wants to deal with one axis at a time, clearly labeled, and making functions that work the way I want them to.
_____________________
-
So long to these forums, the vBulletin forums that used to be at forums.secondlife.com. I will miss them.
I can be found on the web by searching for "SuezanneC Baskerville", or go to
http://www.google.com/profiles/suezanne
-
http://lindenlab.tribe.net/ created on 11/19/03.
Members: Ben, Catherine, Colin, Cory, Dan, Doug, Jim, Philip, Phoenix, Richard, Robin, and Ryan
-
|
|
Oz Spade
ReadsNoPostLongerThanHand
Join date: 23 Sep 2003
Posts: 2,708
|
12-09-2005 16:42
That's another possible solution, turning each axis into a seperate function.
i.e. llDegx, llDegy, llDegz, etc.
But that does take up more function space. Benefit is that the user could order and change each axis how they wish.
However it could be difficult to understand that rotating them in different order produces different results.
_____________________
"Don't anticipate outcome," the man said. "Await the unfolding of events. Remain in the moment." - Konrad
|
|
SuezanneC Baskerville
Forums Rock!
Join date: 22 Dec 2003
Posts: 14,229
|
12-10-2005 01:09
I find doing them one axis at a time makes it much much easier to understand.
When you do actual rotations in the real world along the three axes, it does make a difference which order you do them in. Making the computer do the rotations one axis at a time makes the computer model the way that simple rotations work in the real world.
When you rotate (x, y, z) what order are they rotated in?
If you thought about it as rotating z y x order and the program does it in x y z order you end up oriented the right way.
I made some routines that didn't require so many server updates, they added a variable to store the current rotation, then used functions to do the calculations as if you were rotating the object but without actually rotating the object, instead changing the value or the rotation variable. Still one axis at a time, in degrees. When you get through with the series of twists, then you update the objects actual orientation.
I found that I would not update the objects actual rotation every time and in the exact right place where it was needed.
I think doing rotations as in my functions does away with the gimbal lock problem. Is that correct?
Another way to deal with rotations would be to use a function that would take a list of axes and rotation values.
It would looks something like this:
Spin( ["x", 10, "z", 24, "y", 5, "z", 2] ).
A routine like this could read the object's current rotation at the start into a variable, then do the rotation math on the variable, in order, one axis at a time, then when done processing the list, update the object's position.
Obviously a routine like this in LSL would take extra time determing if it was x or y or z and branching using the needed "if then else" statements. . Execution time is not the only thing that matters in making a programming language for popular recreational usage. Making it fun and simple and easy to understand is also extremely important.
Fun and simple, to most people, does not involve looking in college math books.
_____________________
-
So long to these forums, the vBulletin forums that used to be at forums.secondlife.com. I will miss them.
I can be found on the web by searching for "SuezanneC Baskerville", or go to
http://www.google.com/profiles/suezanne
-
http://lindenlab.tribe.net/ created on 11/19/03.
Members: Ben, Catherine, Colin, Cory, Dan, Doug, Jim, Philip, Phoenix, Richard, Robin, and Ryan
-
|
|
Ben Bacon
Registered User
Join date: 14 Jul 2005
Posts: 809
|
12-10-2005 02:28
SuezanneC, I agree that it should be fun. Fortuanately we don't have to understand college-level maths to use LSL. It does the really hard work for us. What we're left with comes down to two relatively simple concepts. 1. Thinking of angles ranging from 0 to 2*PI is actually far more natural than degrees. Degrees are a completely artificial measure invented by ancient civilisations who had a morbid fascination with "religiously magic" numbers like 12 and 60. They sucked 360 out of their thumbs  . Radians on the other hand are a natural measure of how many times the diameter of the circle fits into the angle you want to measure. - OK - now forget all of that, 'coz all you need to remember is that a full revolution is TWO_PI, half a rev is PI, a quater is PI_BY_TWO. <0, PI, 0> is exactly that same as <0, 180, 0>*DEG_TO_RAD (and easier to read once you get used to it) 2. Most people in RL don't actually rotate things axis by axis. This is usually only done by those of us that were unfortuanate enough to have to learn euler rotations before the world discovered quats. The average layman, if asked to rotate an object from one orientation to another will do so smoothly in one operation. His/her brain will intuitively have picked up on an aribitrary axis (i.e. not x or y or z) around which to perform the rotation. This is exactly how quats work as well. They represent a free-form axis, and an angle to rotate around that axis. This maths is quite complex, which is why LSL does give us llEuler2Rot for when we need it, but it doesn't work with eulers directly so that we, as scripters, can help it avoid having to do that complex maths as much as possible. As far as efficiency is concerned, an open llListen doesn't cause that much lag by itself, right? But a sim full of objects and attachments listening to everything around them can bring a sim's FPS plummeting. Likewise with all other aspects of LSL (rotation included) - we need to co-operatively ensure that our scripts are efficient, so that when 2000 of them run in a sim, they all play together nicely.
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
12-10-2005 11:07
From: SuezanneC Baskerville spinx( float d) { llSetRot( llEuler2Rot( <d*DEG_TO_RAD, 0, 0> ) * llGetRot() ) ; }
spiny( float d) { llSetRot( llEuler2Rot( < 0, d*DEG_TO_RAD, 0> ) * llGetRot() ) ; }
spinz( float d) { llSetRot( llEuler2Rot( < 0, 0, d*DEG_TO_RAD > ) * llGetRot() ) ; } this will be faster... spinx( float d) { d *= 0.0087266462599; //DEG_TO_RAD / 2 llSetRot( <llSin(d),0.0,0.0,llCos(d)> * llGetRot() ) ; }
spiny( float d) { d *= 0.0087266462599; //DEG_TO_RAD / 2 llSetRot( <0.0,llSin(d),0.0,llCos(d)> * llGetRot() ) ; }
spinz( float d) { d *= 0.0087266462599; //DEG_TO_RAD / 2 llSetRot( <0.0,0.0,llSin(d),llCos(d)> * llGetRot() ) ; } even faster... spinx( float d) {llSetRot( <llSin(d *= 0.0087266462599),0.0,0.0,llCos(d)> * llGetRot() ) ; }
spiny( float d) {llSetRot( <0.0,llSin(d *= 0.0087266462599),0.0,llCos(d)> * llGetRot() ) ; }
spinz( float d) {llSetRot( <0.0,0.0,llSin(d *= 0.0087266462599),llCos(d)> * llGetRot() ) ; }
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
SuezanneC Baskerville
Forums Rock!
Join date: 22 Dec 2003
Posts: 14,229
|
12-10-2005 11:41
Thanks, Strife! What a great response that was. I will send you something in return. In addition to my "Rotations for the Rotationally Challenged" routines I also use some routines to move an object along the objects local axes, one axis at a time. movex( float d ) { llSetPos( llGetPos() + (llRot2Fwd( llGetRot() ) * d) ) ; } movey(float d ) { llSetPos( llGetPos() + (llRot2Left( llGetRot() ) * d) ) ; } movez(float d ) { llSetPos( llGetPos() + (llRot2Up( llGetRot() ) * d ) ) ; } These should have a loop added in to them if you want to let "d", the distance moved, be greater than 10. These rotate one axis routines and the move along a local axis routines allow one to convert code written for turtle graphics into LSL quite easily. In the LOGO programming language one uses simple commands to move a turtle that draws things. The code looks sort of like like: "RT 10 FD 2 PEN DN FD 5 ". My version of something comparable would be "spinz(10); movex(2); RezIt(); movex(5)";. This allows one to make 3D turtle graphics constructions easily
_____________________
-
So long to these forums, the vBulletin forums that used to be at forums.secondlife.com. I will miss them.
I can be found on the web by searching for "SuezanneC Baskerville", or go to
http://www.google.com/profiles/suezanne
-
http://lindenlab.tribe.net/ created on 11/19/03.
Members: Ben, Catherine, Colin, Cory, Dan, Doug, Jim, Philip, Phoenix, Richard, Robin, and Ryan
-
|