|
|
|
I already mentioned one overridingly important reason for using PRIM_ROTATION in a child prim: cases in which you need to update the position and rotation simultaneously. This happens in doors and windows, among other things. In these cases, there's no choice but to use PRIM_ROTATION. Also, believe it or not, it is occasionally necessary to set a world-relative position and rotation in a child prim... for example, this is useful in installed, nonmoving link sets that are linked to take advantage of llMessageLinked().
I would recommend that PRIM_ROTATION_CORRECT continue to set the world-relative rotation like PRIM_ROTATION purports to do in order to avoid confusion, and if necessary, add PRIM_ROTATION_LOCAL (and PRIM_POSITION_LOCAL?) that does the equivalent of llSetLocalRot(). Didn't notice this when I posted my feature request
In this event, I'm all for the last proposal here, PRIM_ROTATION_LOCAL and PRIM_ROTATION_CORRECT would be huge benefits. I'm currently working on a project where I really want to update child-prims in a single step, especially with the horrendous lag and packet-loss we've been getting lately, if only the move out of a move/rotate pair makes it through, the result looks awful. I'd prefer it to go through in a single step, this way if it's delayed I don't get pieces floating in odd places or rotated before they've been moved into position. All the functionality (llGetRot() and llGetLocalRot()) is already here as you've mentioned in the original post, it's just a case of setting values in the prim with some degree of sanity. I would of course love to have this sooner rather than later, especially since work has been done on prim-param functions recently that I see no reason to stop now when there are areas that could still be improved before moving onto something else. Are we past the point of no return with this? I.e. is there now too much content that relies on the broken behavior for us to change it now?
I'm afraid we probably are. This bug appears to have been around ever since PRIM_ROTATION and/or llSetRot() in a child prim was implemented. If you look at the forum post I linked to, you can see that people do depend on the current behavior. I think changing this could cause quite a lot of stuff to break, because people tend to experiment with dividing and multiplying quaternions around until things do what they want, without actually knowing how it's supposed to work. Fixing this will probably confuse people even worse and is likely to break some very old content.
I know a fair amount of my stuff relies on the broken behavior, as does that made by people who followed my suggested workaround. I think this bug definitely does need fixing, but I think too much content unfortunately depends on it to fix the behavior in-place. I'm afraid a PRIM_ROTATION_CORRECT style of solution is probably the best way to go. We would need new flags at this point. Fixing the old values is a very bad idea.
That said. You could legacy the old flag value and reuse the name (like what was done with PRIM_TYPE in 1.5.0). It would only bork scripts that were recompiled. It simplifies the documentation if there are PRIM_*_LEGACY flags (for consistency). It makes the documentation look unprofessional to have constants without handles. You don't have to include the PRIM_*_LEGACY flags in drop down box in the script editor but it would be nice if they highlighted. I know old bug is old... but "Recompile scripts in selection" is pretty much permanantly broken now... so it might be a little safer to fix this now. Save still recompiles of course but no end user should be hitting that.
I stumbled upon that problem, too. I agree to Strife Onizuka's suggestion to reassign new values to constants for correct behaviour, though this won't help for llSetRot. My suggestion besides llSetRotCorrect is llSetGlobalRot for a correct implementation of llSetRot. That would complement llSetLocalRot.
Strife's suggestion sounds good.
I think that should be done. I still vote against slamming the PRIM_ROTATION constant to a new value and changing its behavior. I don't like the idea that a simple recompile will take code that worked and make it not work. Someone will invariably go into their ages-old script, change some constant at the top, and suddenly find their rotation math broken. Worse, many people use quaternions without really understanding them fully, so they won't necessarily know how to fix this. Almost no one knows there was a bug in the first place without reading my explanation; see the forum thread linked in the description above.
Rotation math scares people enough. Let's not scare them worse by changing the way their code works out from under them, bolstering their impression that rotation math is not to be trusted. Good point. New flags then but maybe remove the old flags from the highlighter (we don't want to encourage people to use the old flag).
Maybe the new flag should be named PRIM_ROT, short and concise. (i never liked having to type out PRIM_ROTATION) That sounds like a good compromise. I mainly wanted to change the existing ones because I like correctness. but PRIM_ROT sounds just as official as PRIM_ROTATION, so I think it should be done.
And then after that, PRIM_LOCAL_ROT maybe ? Again, I think I want to urge a different path. Having PRIM_POSITION and PRIM_ROT would be confusing. Having PRIM_ROT and a deprecated PRIM_ROTATION seems even more confusing. How will people know which to use? There's no hint in "PRIM_ROT" that this is the new one, the one to use from now on. Plus, "prim rot" sounds like a disease afflicting simulators.
I know it's ugly, but I think we really need to go with PRIM_ROTATION_CORRECT. The thing is, the solution to this is NOT going to be pretty, and I don't think we should let our programmers' aesthetics be injured by something like PRIM_ROTATION_CORRECT. The only thing that would satisfy our sense of API cleanliness would be if PRIM_ROTATION did the right thing in the first place, and it doesn't. We just need to deal with the legacy we have. I don't see PRIM_ROT is confusing, it is what I think it should be, and wish it was anyway, PRIM_ROTATION is a pain to type out, PRIM_ROTATION_CORRECT even more so.
If I had not read this and been aware of the issue, and it was changed to PRIM_ROT, I think I would have seen it become highlighted in the script when it got to PRIM_ROT and I would have left it at that unaware that it had changed. My first problem was that if the root is rotated using llSetPrimitiveParams, than when the link is rotated using the same function, for some angles no rotation takes place. If the root is rotated manually than the rotation works for all angles.
Second problem was that the rotation wasn't relative to the root. I think that the issue you report takes care of the my second problem. Both of our issues are about what happens when llSetPrimitiveParams is used to set the rotation on linked prims. That is why I linked them. I started following the llSetPrimitiveParams() code path which is convoluted (cry) and eventually found this comment (edited for public consumption) in the relevant place:
// [Dev's initials]: this is seriously [$&#*]ed up, but apparently our users work around it Yes, since people have worked around it there is no way to "fix" it because all sorts of content will suddenly break. The only way to resolve the problem is to make a new call, or a new param type (as per the PRIM_ROT vs PRIM_ROTATION_CORRECT) discussion above. (Sigh... it is times like this that I wish we could completely rewrite LSL and the associated callbacks – LSL3!) I'll have to ask Babbage and Don Linden what they think about this bug. Ooh, nice! I was pretty sure about my conclusions, but it's nice to have this confirmed once and for all. I myself have plenty of code that depends on the bug, whether or not I like it, so yeah... just fixing it, tempting though it is, won't work. It really would be nice to have a new param (and don't forget a new function llSetRotCorrect()!) to address this. It'll save us the extra quaternion operations necessary to work , and, according to my description above, the workaround isn't even possible in attachments
You can make it work for child prims of attachments, you just have to pass the root rotation (which is llGetLocalRot() when in the root prim of the attachment) to the child prim in a link message when you're about to play the frame.
oy. just hit my head on this issue, AGAIN.
our transformation API is a complete mess. position is treated differently than rotation. rotation is just plain broken. rotation of attachments is broken. scale is completely ignored. and most obviously, the transformation hierarchy can only be one layer deep. it's embarassing. and it'll be a nightmare to fix. hands Qarl an icepack for his head
Well, thanks for the update, good to know you're aware of it, and good luck! Is there a list of such features, that should be considered in the development of LSL3 or C#?
A conclusion to these comments can be found at http://jira.secondlife.com/browse/MISC-2237
Qarl, please don't fix it! I went through h311 getting my rotating aim-able sensor hud to work and I don't want to do it again
Dahlia - never fear. however it gets fixed, the system needs to maintain backward compatibility for content just like yours.
for example - we might create a new function named "llSetPrimitiveParameters" instead of "llSetPrimitiveParams", and "llSetRotation" instead of "llSetRot"... etc. the old functions would keep their old (busted) behavior. Why isn't there a PRIM_LOCAL_ROTATION yet?
Finally, a Linden understands the mess we have to deal with!
Function renaming* is a good idea but it would require the likewise named functions to also be renamed too, I recommend removing the old functions from the highlighter (god only knows how you do that!) so they can still be used but not clog up the dropdown. Is it non-trivial to add a PRIM_LOCAL_ROTATION parameter to llSetPrimitiveParams? We've been waiting for a fix for two years now, what gives?
Blasphemy! We couldn't have such a simple solution Chris. We need one that breaks huge amounts of content and confuses the heck out of people.
It seems pretty trivial on the face but there are some complications. Code for both attachments and child prims need to be straightened out... then expanded to work with both llGetPrimitiveParms and llSetLinkPrimitiveParams
This seems like the best solution, then mark the other ones for deprecation on the wiki. That way the names still make sense and people know not to use them. Then at some point just get rid of the pages and act like they don't exist On a side note:
That just sounds like being anal. You wouldn't have to rename all the likewise named functions. For anyone that does care they will just go "Huh that is strange. Oh well." , move on and never think about it again. Why make more work than there has to be, just to make it look a little neater. "llSetPrimitiveParameters"
"llSetPrimitiveParams" "llSetRotation" "llSetRot"... etc ... That seems to be the unavoidable short-term workaround. But to a certain degree it also shows, that LSL2 is a dead end. The important comments here are: "Sigh... it is times like this that I wish we could completely rewrite LSL and the associated callbacks - LSL3!" and "our transformation API is a complete mess. position is treated differently than rotation. rotation is just plain broken. rotation of attachments is broken. scale is completely ignored. and most obviously, the transformation hierarchy can only be one layer deep." The only reasonable conclusion that came to my mind is summarized here: http://jira.secondlife.com/browse/MISC-2237 Please, please, PLEASE do not create "llSetPrimitiveParameters()" and deprecate "llSetPrimitiveParams()" as a fix to this issue. While this would, technically, solve the problem, and it might even look tempting from an aesthetic point of view, think of how this will seem to people who were not privy to this conversation. A new LSL programmer, trying to learn the language, will be incredibly confused by the two similarly-named functions, and it will seem incredibly arbitrary that the difference between the two is merely that one works properly. That's the kind of gotcha that would make a language like this very frustrating to learn.
I'd much rather see PRIM_ROTATION_CORRECT and llSetRotCorrect(). I know these look like warts on the language, but at least they serve to make it clear to new LSL programmers that something weird is going on here and that they need to investigate further.
First, anyone who can read can see at the top of the function page not to use functions marked for deprecation. Second just change the page of the old function to say use the new function and link to it, that would be the only thing on its wiki page. Then I don't know about you but last I checked deprecation means at some point the functions listing and page will be removed. If any confusion does occur which I will presume very little will if they read the pages, it will only happen for a short period of time; a few months or so. In the long term I think this is a sacrifice that should be made. Personally if at some point llSetRotCorrect existed but not llSetRot i'd probably get confused as to why its called that. I'm sure either way there might be very little confusion and i'd much rather come out of it with functions names that make more sense, specifically when learning it. My feelings on new function vs new parameter constant: Whichever way we go, it'll be another wart on the language, but there's no way to avoid a wart while still retaining backwards compatibility. So, we ought to pick the less disruptive, more maintainable, and more usable wart – which I think is a new parameter constant, in particular PRIM_ROTATION_CORRECT. I'll elaborate:
Now, eventually – hopefully – LSL2 will be superceded by LSL3 or some other language, and the designers of that language can avoid the mistakes and warts of LSL2. But until that day comes, we're stuck with LSL2, so I want it to be the most usable language it can be. Achieving that requires keeping in mind the realities of human memory and the environment in which the language will be used, rather than pursuing the abstraction of superficial cleanliness. Thank you, Jacek, for a very lucid argument in favor of PRIM_ROTATION_CORRECT. One more argument in its favor occurred to me as I was reading your comment. If LL does go with "llSetPrimitiveParameters()", they would also have to create "llSetLinkPrimitiveParameters()". Furthermore, then we'd have the confusing dichotomy of llSetPrimitiveParameters() and llGetPrimitiveParams() which will make things even more confusing.
Thanks for so clearly describing the problem.
The only reason for choosing function renaming in my mind is to keep the constant names short... which while well meaning causes bigger problems then it solves (hence the asterisk in my previous comment... which I forgot to elaborate on). the big problem with using a token like PRIM_ROTATION_CORRECT is that it only works once. the next time we need to make an adjustment, things just become silly (PRIM_ROTATION_NOTHISONEISTHERIGHTONE.)
and - in 10 years, when this issue is long forgotten, _CORRECT will be out of place. perhaps if we use _CORRECT as a temporary crutch? i'm not sure. we should see what other APIs/languages do when they need to make a change like this. But Qarl, that's also an argument for not going the llSetPrimitiveParameters route. What if you need to make a correction to the functionality of some other prim-param constant? llSetPrimitiveParamerthingies()? The function-renaming route just compounds that problem.
I agree with seeing how other APIs have dealt with this. But Qarl, that's also an argument for not going the llSetPrimitiveParameters route. What if you need to make a correction to the functionality of some other prim-param constant? llSetPrimitiveParamerthingies()? The function-renaming route just compounds that problem.
I agree with seeing how other APIs have dealt with this. @Qarl: Hopefully, this time there will be a suite of unit tests proving beyond a doubt that the mathematics involved are actually correct. Right?
And as Lex says, the problem you mention exists with the "make a new function" strategy too, only to a much, much greater degree. Every time you discover a single parameter is wrong, you'd have to create at least 3 new functions to correct the behavior (Get, Set, and SetLink). If you wanted to be certain that the new function is correct (and thus won't require yet another function being added later), you'd have to create a suite of new unit tests for every parameter it supports (and every argument those parameters accept), rather than just the one parameter that was fixed/added. Both solutions are icky, but I think a new constant is by far the lesser of two icks. (P.S. I certainly hope that we won't still be using LSL2 in the year 2019! You're scaring me, talking like that! o_O) The real answer is that the LSL library functions are supplied in different versions, so that scripts use the version they're compiled with, until the developer sets them to a different version. Which leads into we could do with library support in LSL, and back to the fact that LSL really needs to be taken outside, shot in the head, and replaced with something saner.
So lets go with PRIM_ROTATION_CORRECT until we can get a sensible scripting language in? Versioning is one way. That can be done with libraries or with a version flag (LSL version [2.0|v] with a pulldown offering 1.2, 1.3, 2.0, 2.1, 3.0, ...) or with feature tests (#feature prim_param_rotation_2).
Another way is to create new named or numbered functions (seek, lseek, llseek, or wait, waitpid, wait2, wait3, wait4). As for something saner, I vote for Forth! The underlying bytecode is already stack-oriented. (no, wait, stop, I was kidding, owahhh, that hurts) More seriously, how about LOGO? My votes are for PRIM_ROT_LOCAL and PRIM_ROT_GLOBAL, with an explanation of the deprecated PRIM_ROTATION for those curious. Each would need a new number.
The more serious error is that the code is unmaintainable, so that the crew can't take the time to figure how much time would be required. Finding that sucker is a halting problem of intimidation. The Code of llSetPrimitiveParams, llGetPrimitiveParams, llSetLinkPrimitiveParams, llGetLinkPrimitiveParams and llGetObjectPrimitiveParams has got to be straightened out to maintainable, before some point in the history of Open Grid. In addition to llGetObjectPrimitiveParams(), I'd also like llGetAvatarTarget(), which doesn't seem to be avatar position. I'd also like some way of finding an object in inventory and saying, "Make me look like that, in these listed features." Qarl if we are still using the LSL2 function API in 5 years let alone 10 years... you better hope you are out of the office the day I stop by.
Seriously LSL needs to be rebuilt and redesigned from the ground up. We have been hobbling along for years, we keep slapping new functionality on without properly cutting away the dead wood. Do you know off hand (no cheating) which one of these is deprecated: llPreloadSound or llSoundPreload? I sure don't. The situation is terrible and creating new functions doesn't solve this problem. Now don't forget there is a third option and it was the option taken in 2004. In 2004 the value of PRIM_TYPE (1) was retired, and the constant was assigned a new value (9); this radical change broke code but brought new functionality. I believe Don Linden spear headed the project and it turned out well; all of the bugs in the old interface were fixed and some of the feature suggested were implemented (Guess who suggested twist on spheres _). If you are worried about naming... why not: but if history is any indication of the future, then in 2019 when LL finally has all the bugs worked out it will be Personally I would like C# 3.0 (or better yet 4.0 _) I brought this up last Thursday, along with the obligatory SVC-22, at Simon (San Andrew) Office Hour, and pretty much came to the conclusion that all PrimitiveParams, llGet-llSet, Link and Other, needs to be rewritten, from a blank piece of paper. I don't know what level of development training this would be appropriate for but, a Blank Paper Team should be organized on this legendary problem, as an excersize in Maintainable Code.
Talk about PrimitiveParamatersV4And20 is nonsense, since PRIM_ROT_LOCAL and PRIM_ROT_GLOBAL are just a couple Integers, and it's the underlying code that is a problem of Maintainability. I wonder if all unmaintainable code should be held as a possible effort to hijack Job Security, and penalized Triple Damages. 'Sup guise; totally uneducated, inexperienced, new-as-in-I've-only-been-on-SL-for-less-than-a-week person here to rant for a little while. But hey, I'm the sort of person a fix of this issue would affect, so maybe that makes my opinion a little more useful? Just don't mind the fact that I haven't finished college Calc II, let alone linear algebra (I'm sure it'll be fun though, given what I've tried to read thus far about quaternions), and don't know a thing in the world about API's, the structure of programming languages, or any other important things that make me sound like I'm not a moron and actually know what I'm talking about.
Hm. A bit of a pipe dream, but wouldn't it be possible to do a huge find/replace operation in the affected content's source code to replace the broken function+workaround with the syntax for a corrected implementation, then recompile everything? Surely Linden Labs has access to all the content in Second Life. Just take all the servers down for a few days, explain to the users what's going on and why this is happening, and just do it? If I may input my two cents though, I think that the longer everyone spends debating how to fix the issue, the more instances of the broken function being used will arise. This has been an issue for two years, and there is still no resolution. Think of how many more scripts that utilize the broken llSetRot function and its workaround have been created since the issue was first reported. If the problem is, in fact, just a misplaced operator, then shouldn't priority be placed on just getting a fix out there? LSL is not, from my experiences, something that most people can just pick up without referring to the wiki or some other reference source at some point. As an inexperienced scripter, I knew that from the beginning, and never hesitated to refer to the LSL Portal when I needed to know exactly how to use a function. There's already enough convolution to the current set of functions to justify adding one more. No, it doesn't look very professional to have a dozen revised and depreciated functions out there, but by the same token, is it any more professional to leave a broken function in place? "Rules of rotation older than contact with JIRA. Did not mention correctness. Rules change caught up in committee. Not come through yet."
Wow.. Almost unbelievable.
Right now, while you are reading this, how many people are making more things using bork3d bits,.. Delaying the inevitable only increases the number of failures when crunch time comes. I start hunting down why only llSetLocalRot works in my linked structure.. when ideally I'd like to use one function call to change rotation & several other parameters (aka llSetPrimitiveParams) & here I find an age old issue, with ridiculous talk of adding functions or constants. Fix the root of the problem & do it now; For the sake of the masses. I wouldn't mind changing the current functionality, and breaking old content that uses it. It's not too difficult to change the one line where it's currently used in your scripts
That said, this is only from a personal view. I'm not advocating that course of action, merely saying that I wouldn't object if it were taken. It seems like the most "correct route" I think, the answer could lie in better documentation. For example, when a script is being compiled, the compiler could check the date when it was last compiled, and compare it against a list of known deprecated or otherwise significantly changed functions. And issue a warning to the user something to the effect of "The function <name> has been significantly changed since this script was last compiled. Your current use of it may be incorrect, and cause problems in your application. Please check <url> for how it should work, and ensure your script is designed for this." WarKirby: would you be willing to go through and help the Lindens find all the products that would break that aren't currently supported (especially for creators who are no longer in SL)?
While I'm very hateful of the current situation that existed from before my secondbirth.
And I despise that despite the apparent triviality of adding PRIM_ROTATION_LOCAL and PRIM_ROTATION_WORLD options hasn't born fruit. I'm not ready to suggest causing copy-paste scripters and whoever decides to recomplile their items so much trouble that they can't necessarily fix by swapping out the function on next compile. Bad idea, lets add some new correct bits and move on. Preferably before the decade is up? I strongly feel that any change which would break/change the behavior of existing scripts when they are recompiled is out of the question. Needing to update the old scripts would be an utter nuisance for even the most knowledgable scripters, and a complete showstopper for less capable scripters and non-scripters. That means: no new behavior for llSetRot or PRIM_ROTATION, period.
I'm fine with PRIM_ROTATION_LOCAL and PRIM_ROTATION_GLOBAL, and a new llSetGlobalRot() function. Deprecate llSetRot and PRIM_ROTATION but leave their behaviors the same. If I recall correctly, llSetLocalRot() works correctly, so it should not be changed. Or call it WORLD/World instead of GLOBAL/Global (though "global" is the more standard term, I think), or PRIM_ROT_* instead of PRIM_ROTATION_*, if you want to. I concur with the sentiment of "Let's fix it already". This is dragging on way too long. The only question I have about llSetGlobalRot() would be – what would be the behavior for attachments and HUDs? llSetRot() and llSetRotLocal() seem to behave identically for root prims in attachments, i.e. they set rotation relative to the joint they are attached to. Although, llGetRot() seems to return the avatar's rotation, so llSetRot( llGetRot() ) changes rotation, which is weird and unexpected. The options for llSetGlobalRot() for attachment and HUD behavior would seem to be:
I'd suggest #1, but also adding llGetGlobalRot() and officially defining "global" space for attachments to mean relative to the joint. I'd deprecate llGetRot() as well. *sigh*, LSL rotations are so inconsistent and bizarre. I wish whoever designed this stuff in the first place had put more forethought into it. I'd just like to add my voice to the "Don't break existing content" camp (placard waving included). Any change in the code that results in past work being broken would be a disaster. It's all very well saying that things can be fixed after (by the scripter) but if an item is not mod and not owned by the scripter and is not subject to auto updates, who is going to fix it? 13.500 regions 15,000 prims per region. Big numbers.
However rotation is a mess and needs a full overhaul. Could a new set of functions be created to replace (edit: Not replace but co-exist with) llSetLink and llSetPrimitiveParams and all the associated shortcut functions? Having the old and new would allow that all future scripts work perfectly while all old scripts work just as well as they ever did. I realize this would be a massive job but lots of other issues could then be fixed while it was being created. Such as the implimentation of the related llGetLinkPrimitiveParams and the inclusion of a much needed allowance to select a subset of children with llGet and llSetLinkPrimitiveParams. I spake. Jacek: LSL was built organically, it wasn't really designed. It's one of those things that would benefit greatly from being redesigned with the current feature sets in mind. Unfortunately the cost of rebuilding LSL from the ground up might be greater than adding support for a mature language like C#. Being able to deprecate LSL with a properly designed OO language might just make things easier for everyone.
Strife: There's a push towards supporting C# (and other non-LSL languages) in SL now. The Mono VM will support pretty much anything you fancy, the only major component missing is security code to verify scripts before they're run. There's a bunch of us working with Babbage Linden ( http://wiki.secondlife.com/wiki/User:Babbage_Linden
Hopefully once we're off the madness that is LSL, we'll see more functions coming in. I certainly get the impression the Lindens are holding off making changes because they don't want to just keep piling stuff on top of the existing mess. "A properly designed OO language" would mean "a language designed for OO from the ground up, like Smalltalk" not "a language grown organically from C", like... well, far too many modern "OO" languages. I'm sure Churchill had an aphorism for this situation.
This is still a problem. I use llSetRot() to set the rotation of some objects. They don't actually move there as seen in my viewer until I right click on them and "edit" them.
I was able to hack around it by adding llSetText("x", <1., 1., 1.>, 1.0); right after the llSetRot() command. That evidently convinces the viewer that there's a real update that needs to be done. Prospero, that's a different issue, see SVC-1945 and vote for it if you want.
The suggested names llSetRotationCorrectly(), PRIM_ROTATION_CORRECT look like a wart.
I suggest using these names instead: llSetGlobalRot( rotation globalrot ) – same as llSetRot but works correctly on child prims [PRIM_GLOBAL_ROT, globalrot ] – same as PRIM_ROTATION but works correctly on child prims and whenever somebody adds those, now that they're at it, the could as well add something new: [ PRIM_LOCAL_ROT , localrot ] llSetRot and PRIM_ROTATION should not be deprecated at all, because they work fine on root prim and have short, good names. But their use on child prims should be strongly discouraged (not deprecated) if/when llSetGlobalRot and PRIM_GLOBAL_ROT are available. (added some jira mark-up to the description to improve readability)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
An additional function llGetAttachmentRot should be added to return the rotation of the root of an attachment relative to the attach point (if the object is not attached it should return the same value as llGetRootRotation).