• All submissions to this site are governed by Second Life Project Contribution Agreement. By submitting patches and other information using this site, you acknowledge that you have read, understood, and agreed to those terms.
Issue Details (XML | Word | Printable)

Key: SVC-93
Type: Bug Bug
Status: Open Open
Priority: Critical Critical
Assignee: Andrew Linden
Reporter: Lex Neva
Votes: 110
Watchers: 40
Operations

If you were logged in you would be able to see more operations.
2. Second Life Service - SVC

llSetPrimitiveParams PRIM_ROTATION and llSetRot incorrectly implemented for child prims

Created: 06/Apr/07 09:34 AM   Updated: Sunday 09:56 AM
Component/s: Scripts
Affects Version/s: 1.13.4
Fix Version/s: None

Issue Links:
Parent/Child
 
Relates
 

Linden Lab Issue ID: DEV-1178


 Description  « Hide
This bug has been around for at least a year. In short, llSetPrimitiveParams([PRIM_POSITION, ...]) and llSetRot in a child prim is implemented incorrectly, resulting in unexpected results. I've been able to determine the exact nature of the implementation bug and have reported this in the past, but nevertheless the issue remains. I believe this is because rotation math is tricky stuff, so not many people notice that anything is actually wrong.

In a child prim, it the rotation of a child prim is stored internally by SL as a rotation relative to the root prim of the link set. llSetLocalRot() sets this rotation verbatim. llSetRot() in a child prim should set the prim such that its world-relative rotation is equal to the argument passed.

Logically, the following should be a no-op in a child prim:

llSetLocalRot(llGetLocalRot());

It is, in fact. The following should also be a no-op in a child prim:

llSetRot(llGetRot());

It's not. The result is that the child prim rotates some amount every time the preceding line is run.

Since child prim rotations are stored as a rotation relative to the root prim, the following should be a pseudo-implementation of llSetRot() in a child prim:

llSetRot(rotation rot) {
        llSetLocalRot(rot/llGetRootRotation());
    }

The above code uses rotation division. In essence, this says, "tell me rot as a rotation relative to llGetRootRotation()". This is how quaternions work.

Through extensive testing, I've determined that it's actually implemented as the following:

llSetRot(rotation rot) {
        llSetLocalRot(rot * llGetRootRotation());
    }

That's right: the internal code that implements llSetRot() and PRIM_ROTATION for child prims uses a quaternion multiplication when it should use a division. I'm absolutely sure of this.

To work around this, normally it's enough to just avoid using llSetRot() in a child prim, and to get the same functionality by using llSetLocalRot() as I showed above. However, if it's critical that the rotation and position of a child prim are set at the same instant, the only possible way to do this is llSetPrimitiveParams([PRIM_POSITION, ..., PRIM_ROTATION, ...]);. This means that you have no choice but to use the buggy PRIM_ROTATION implementation.

If you must set a child prim to a world-relative rotation rot using PRIM_ROTATION (or llSetRot()), use this:

llSetPrimitiveParams([PRIM_ROTATION, (rot / llGetRootRotation) / llGetRootRotation);

If you must set a child prim to a local rotation rot using PRIM_ROTATION, use this:

llSetPrimitiveParams([PRIM_ROTATION, rot/llGetRootRotation]);

Furthermore, llGetRootRotation does not return a meaningful result for child prims in attachments.

Those examples both illustrate quaternion math that does not make sense. They only work because of the errant multiply operation carried out behind the scenes. Countless scripters in-world and in the forums have essentially stumbled upon these workarounds by doing various quaternion operations until the right thing happens[1]. I (and possibly others) worked out the actual problem and use the above workarounds routinely when I need to. Simply fixing PRIM_ROTATION will, unfortunately, break a lot of content. A new function, llSetRotCorrectly(), and a new operation, PRIM_ROTATION_CORRECT, will need to be implemented to fix this bug.

As nearly as I can tell, this bug has been around since llSetRot() was first implemented, and was carried on when llSetPrimitiveParams() was implemented.

[1] http://forums.secondlife.com/showpost.php?p=943944&postcount=2



 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Strife Onizuka added a comment - 06/Apr/07 11:12 PM
The usefulness of llSetRot in a child prim is dubious at best, I think that PRIM_ROTATION_CORRECT and llSetRotCorrect should both work in child-prims as local to the root.

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).


Lex Neva added a comment - 07/Apr/07 08:34 AM
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().


Haravikk Mistral added a comment - 12/Apr/07 04:05 PM
Didn't notice this when I posted my feature request SVC-102 (which you've already linked, cheers).
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.


Rob Linden added a comment - 28/Sep/07 01:35 PM
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?

Lex Neva added a comment - 29/Sep/07 10:59 AM
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.


Strife Onizuka added a comment - 02/Oct/07 06:57 AM
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.
PRIM_ROTATION_LEGACY - has the old PRIM_ROTATION value
PRIM_TYPE_LEGACY - has the old PRIM_TYPE value. There is a PRIM_TYPE_LEGACY flag in the internal enumeration but it hasn't been exposed to compiler with a keyword.

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.


Lex Neva added a comment - 02/Oct/07 08:24 AM
It's a possibility. I wonder how likely this is to break some poor programmer's brain when they happen to recompile a script after making a minor change and find their rotation math is broken?

Gigs Taggart added a comment - 09/Nov/07 11:56 PM
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.

Thomas Shikami added a comment - 22/Nov/07 02:38 PM
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.

WarKirby Magojiro added a comment - 26/Nov/07 09:04 AM
Strife's suggestion sounds good.

I think that should be done.


Lex Neva added a comment - 26/Nov/07 09:16 AM
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.


Strife Onizuka added a comment - 26/Nov/07 06:52 PM
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)


WarKirby Magojiro added a comment - 27/Nov/07 05:08 AM
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 ?


Lex Neva added a comment - 27/Nov/07 10:12 AM
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.


Saskia McLaglen added a comment - 08/Dec/07 12:47 AM
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.


Rex Cronon added a comment - 14/Jul/08 02:28 PM
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.

Andrew Linden added a comment - 14/Aug/08 11:23 AM
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.


Lex Neva added a comment - 14/Aug/08 11:53 AM
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.

Seifert Surface added a comment - 14/Aug/08 12:06 PM
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.

Qarl Linden added a comment - 28/Dec/08 03:28 PM
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.


Xugu Madison added a comment - 28/Dec/08 03:37 PM
hands Qarl an icepack for his head

Well, thanks for the update, good to know you're aware of it, and good luck!


Arawn Spitteler added a comment - 03/Jan/09 12:10 PM
Is there a list of such features, that should be considered in the development of LSL3 or C#?

Theblack Box added a comment - 23/Jan/09 01:58 PM
A conclusion to these comments can be found at http://jira.secondlife.com/browse/MISC-2237

Dahlia Trimble added a comment - 18/Feb/09 01:20 PM
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

Qarl Linden added a comment - 18/Feb/09 01:32 PM
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.


Huns Valen added a comment - 01/Apr/09 05:58 PM
Why isn't there a PRIM_LOCAL_ROTATION yet?

Strife Onizuka added a comment - 02/Apr/09 05:38 AM
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.


Christopher Omega added a comment - 04/Apr/09 03:23 PM
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?

Strife Onizuka added a comment - 05/Apr/09 04:40 AM
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


Ikryn Gurbux added a comment - 13/Apr/09 06:38 AM

Qarl Linden added a comment - 18/Feb/09 01:32 PM
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.

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 I assume that one the reasons this might be taking a while, in addition to it being a mess, is they might be looking through all of it, to not only improve it but fix any errors that still might be in there before they make their way to the surface. At least that's what im hoping. Until llSetPrimitiveParameters and llSetRotation come out though I guess i'll stick with the work around

On a side note:

Strife Onizuka added a comment - 02/Apr/09 05:38 AM
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.

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.


Theblack Box added a comment - 14/Apr/09 05:50 AM
"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
And is waiting for comments


Lex Neva added a comment - 14/Apr/09 07:18 AM
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.


Ikryn Gurbux added a comment - 14/Apr/09 03:46 PM - edited

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.


Jacek Antonelli added a comment - 14/Apr/09 06:20 PM
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:
  • As others have said, llSetPrimitiveParams vs llSetPrimitiveParameters is confusing. Which one are you supposed to use? Even if the older one is documented as being deprecated, the confusion will still exist. Programmers will have to keep checking the docs to make sure they are remembering correctly, which is a nuisance that can be easily avoided. PRIM_ROTATION_CORRECT does not have this problem: the name itself indicates that it should be preferred over PRIM_ROTATION. The programmer would only have to consult the documentation once, if they are curious as to why there are two similar constants.
  • Given the widespread use of llSetPrimitiveParams in existing code, programmers (even new ones) will find it necessary to be aware of both the old system and the new system, whether it be a function or a new constant, because they will inevitable encounter the old system "in the wild". It's easier to learn and remember the difference between PRIM_ROTATION and PRIM_ROTATION_CORRECT, than to try and remember which parameters differ in behavior between llSetPrimitiveParams and llSetPrimitiveParameters.
  • Likewise, upon encountering the code "llSetPrimitiveParams( [PRIM_ROTATION, ...] )", there is a high potential for confusion if PRIM_ROTATION has two different meanings. The programmer would have to keep checking the documentation to make sure they know which behavior corresponds to which function. PRIM_ROTATION_CORRECT does not have this problem.
  • Adding a new function to fix one broken param is unnecessary, and poor planning for the future. One of the strengths of llSetPrimitiveParams is that you don't need to create a new, competing function every time you want to add something new. For example, when sculpties and flexi prims were introduced, they didn't require new functions be added to the language, just new parameter constants. The same reasoning applies to fixing rotation, because it involves adding a new line of functionality, rather than changing the old one in place.

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.


Lex Neva added a comment - 15/Apr/09 07:22 AM
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.

Strife Onizuka added a comment - 15/Apr/09 10:12 PM
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).


Qarl Linden added a comment - 15/Apr/09 10:24 PM
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.


Lex Neva added a comment - 15/Apr/09 11:04 PM
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.


Lex Neva added a comment - 15/Apr/09 11:04 PM
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.


Jacek Antonelli added a comment - 16/Apr/09 12:07 AM
@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)


Xugu Madison added a comment - 16/Apr/09 02:49 AM
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?


Argent Stonecutter added a comment - 16/Apr/09 05:15 AM
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?


Arawn Spitteler added a comment - 16/Apr/09 05:06 PM
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."


Strife Onizuka added a comment - 16/Apr/09 11:58 PM
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:
PRIM_ROT_V2
then later
PRIM_ROT_V3

but if history is any indication of the future, then in 2019 when LL finally has all the bugs worked out it will be
PRIM_ROT_V21

Personally I would like C# 3.0 (or better yet 4.0 _)


Arawn Spitteler added a comment - 21/Apr/09 08:39 AM
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.


Cobalt Arkright added a comment - 22/Apr/09 04:18 PM
'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?
Okay, so that's probably not such a great idea, given the sheer volume of code needing to be processed. But it was worth a shot mentioning, right?

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?


Elbereth Witte added a comment - 22/Jun/09 05:09 PM
"Rules of rotation older than contact with JIRA. Did not mention correctness. Rules change caught up in committee. Not come through yet."

Damen Hax added a comment - 12/Jul/09 12:02 AM
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.


WarKirby Magojiro added a comment - 31/Jul/09 02:19 AM
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."


Argent Stonecutter added a comment - 31/Jul/09 04:15 AM
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)?

Elbereth Witte added a comment - 31/Jul/09 01:55 PM
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?


Jacek Antonelli added a comment - 31/Jul/09 03:34 PM
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:

  1. Set rotation relative to the joint it's attached to. "Global" would be misleading, but it would be consistent with llSetRot() (but inconsistent with llGetRot()).
  2. Attempt to set rotation in global coordinates, compensating for the avatar's (actually, agent's) rotation. But this will almost never seem to work right, due to avatar poses and animations. So, this is a bad option.
  3. Attempt to set rotation in global coordinates, compensating for the avatar's pose, too. This would require a lot of server and viewer work to communicate the pose, and would be unreliable. So, I don't think it's really an option at all.
  4. No-op, do nothing when run from an attachment. Maybe add llSetAttachmentRot() to make up for the missing functionality.
  5. Alternatively, emit an error message that llSetGlobalRot() can't be used in an attachment, and they should use llSetAttachmentRot() instead.

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.


EddyFragment Robonaught added a comment - 31/Jul/09 04:09 PM - edited
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.


Strife Onizuka added a comment - 03/Aug/09 05:32 AM
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.

Xugu Madison added a comment - 03/Aug/09 06:10 AM
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 - office hours 0300 SLT Wednesdays) to help with provide test cases for this, and we could always do with more help: http://xugumadison.org/csharp-sl/index.php?title=Main_Page

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.


Argent Stonecutter added a comment - 03/Aug/09 06:11 AM
"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.

Prospero Frobozz added a comment - 12/Aug/09 04:54 PM
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);
llSetText("", <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.


Jules Joffe added a comment - 26/Aug/09 08:04 AM
Prospero, that's a different issue, see SVC-1945 and vote for it if you want.

Wolfie Waves added a comment - 24/Sep/09 05:17 PM
Still no fix for this

Takni Miklos added a comment - 25/Oct/09 04:19 PM
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 ]
– does the same thing as [ PRIM_GLOBAL_ROT , localrot * llGetRootRotation() ] on child prims
– works only on child prims, it just does nothing on root prim

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.


Boroondas Gupte added a comment - 15/Nov/09 04:18 AM
(added some jira mark-up to the description to improve readability)