[JIRA] Commented: (SVC-93) llSetPrimitiveParams PRIM_ROTATION and llSetRot incorrectly implemented for child prims

EddyFragment Robonaught (JIRA) no-reply at lindenlab.cascadeo.com
Sun Nov 22 20:45:10 PST 2009

    [ http://jira.secondlife.com/browse/SVC-93?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=148076#action_148076 ] 

EddyFragment Robonaught commented on SVC-93:

Rob Linden added a comment - 28/Sep/07 01:35 PM
Are we past the point of no return with this?

...and getting further and further away as time marches on...

> llSetPrimitiveParams PRIM_ROTATION and llSetRot incorrectly implemented for child prims
> ---------------------------------------------------------------------------------------
>                 Key: SVC-93
>                 URL: http://jira.secondlife.com/browse/SVC-93
>             Project: 2. Second Life Service - SVC
>          Issue Type: Bug
>          Components: Scripts
>    Affects Versions: 1.13.4
>            Reporter: Lex Neva
>            Assignee: Andrew Linden
>            Priority: Critical
> 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:
> {code}
>     llSetLocalRot(llGetLocalRot());
> {code}
> It is, in fact.  The following should also be a no-op in a child prim:
> {code}
>     llSetRot(llGetRot());
> {code}
> 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:
> {code}
>     llSetRot(rotation rot) {
>         llSetLocalRot(rot/llGetRootRotation());
>     }
> {code}
> 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:
> {code}
>     llSetRot(rotation rot) {
>         llSetLocalRot(rot * llGetRootRotation());
>     }
> {code}
> 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:
> {code}
>     llSetPrimitiveParams([PRIM_ROTATION, (rot / llGetRootRotation) / llGetRootRotation);
> {code}
> If you must set a child prim to a local rotation {{rot}} using PRIM_ROTATION, use this:
> {code}
>     llSetPrimitiveParams([PRIM_ROTATION, rot/llGetRootRotation]);
> {code}
> 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

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators: http://jira.secondlife.com/secure/Administrators.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira


More information about the Jira-notify mailing list