Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Child Rotation broken?

Sinavestos Dassin
Registered User
Join date: 1 May 2006
Posts: 3
05-20-2006 10:09
Okay I've been trying to figure out if it's just my misunderstanding of the rotation functions, or if something is actually bugged here, and I'm fairly sure it's b.)ugged :-/ Basically, I've set up a test object, which is just a stationary, non-scripted cube for a parent object, and a scripted rectangle as a child object. So, I've linked them, and I was messing around with rotations and junk when I realized something didn't seem to be working right. I simplified the script quite a bit, and now I'm convinced that llSetPrimitiveParams([PRIM_ROTATION, ...]) is bugged when used in a child object.

default
{
state_entry()
{
lpos = llGetLocalPos();
rot = llGetRot();
vector erot = llRot2Euler(rot) * RAD_TO_DEG;
llSay(0, (string)erot);
llSetPrimitiveParams([PRIM_POSITION, lpos, PRIM_ROTATION, ZERO_ROTATION]);
}
}

Okay, so I set the parent object to a rotation of 0, 0, 300 (x, y, z rotation). The child object is aligned with it, so it has identical rotation. Now, according to the wiki, llSetPrimitiveParams works like llSetRot, so it should be root-relative. However, when I run this script, the child object ends up being set to a rotation of 0, 0, 240. This doesn't make *any* sense ... as if llSetPrimitiveParams/llSetRot was done with an absolute reference frame, it should have set it to a rotation of 0, 0, 0 ... if not, it should be set to 0, 0, 300. So I did some more tests, and it turns out that every time, the child object gets set to *double* the rotation of the parent. I believe what's happening (the only explanation I can come up with that would make any sense at all, though it's quite possible that I'm totally wrong here) is that when llSetRot(ZERO_ROTATION) is called from a child object, it's using the parent objects *local* axes as a basis for rotation ... but then, it adds the parent object's *global* rotation onto those axes, meaning it ends up rotating twice as far as it should. Whatever the case is, it's driving me nuts. Does anyone know if this is a bug, or am I just missing something here?

FYI, I have been poking around with it a bit more, and this seems to be the line of code that works to actually set the local rotation of the child prim to match that of the parent.

rotation rot = llEuler2Rot(<0,0,0>;) / ( (ZERO_ROTATION / llGetLocalRot()) * llGetRot());
llSetPrimitiveParams([PRIM_ROTATION, rot]);

Note that for some reason, llEuler2Rot(<0,0,0>;) != ZERO_ROTATION. When that statement was:
rotation rot = ZERO_ROTATION / ( (ZERO_ROTATION / llGetLocalRot()) * llGetRot());
It acted exactly the same as if I called llSetPrimitiveParams([PRIM_ROTATION, ZERO_ROTATION]);. Apparently I am not fully comprehending how the rotation calculations work ... maybe I should go back to actually handling the quaternions with matrix multiplications as I have to do in things in C++, but something tells me that would slow my scripts waaaaay the hell down. Anyways, I seem to have managed to find a workable code snippet that solves this problem, but I still don't know *why* it works, and it always bugs me when I manage to fix a bug in my code through trial and error without actually understanding wtf is going on. If any of you scripting gurus out there could explain what's going on here, I would seriously appreciate it. Thanks :)

EDIT: Hmm, I think I've figured it out. I guess ZERO_ROTATION equates to a completely null rotation, meaning it won't affect the rotation of the prim, whereas llEuler2Rot(<0,0,0>;); explicitly sets the rotation to align with the current axes ... in this case setting them equal to the parent object. While this does explain why llEuler2Rot(<0,0,0>;) != ZERO_ROTATION, and my code is now working smoothly, I must admit I am still somewhat perplexed as to the initial question in this post. What was going on with the doubling of the parent's rotation? I'll probably be fiddling with this for awhile ... if I figure out anything I'll edit this post again, and if anyone out there knows what's up here, I'd really appreciate you helping my brain avert a major geometry-induced meltdown. Thanks again ;)
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
05-20-2006 10:59
From: Sinavestos Dassin
...So I did some more tests, and it turns out that every time, the child object gets set to *double* the rotation of the parent. I believe what's happening (the only explanation I can come up with that would make any sense at all, though it's quite possible that I'm totally wrong here) is that when llSetRot(ZERO_ROTATION) is called from a child object, it's using the parent objects *local* axes as a basis for rotation ... but then, it adds the parent object's *global* rotation onto those axes, meaning it ends up rotating twice as far as it should.



You're right. It's bugged. The effect is pretty much exactly as you described, but the reason for it is simpler than you think... just an accident of programming in the way PRIM_ROTATION (and llSetRot() in a child prim) was implemented.

Here's a more detailed description of exactly what's going on and how to get around it:

/54/c1/94705/1.html

The best way around it is to use llSetLocalRot(). If you really want to use llSetPrimitiveParams() (ie to set more than one thing at once), check that thread for a workaround.

Also, please bug-report this. The more voices, the better.
Sinavestos Dassin
Registered User
Join date: 1 May 2006
Posts: 3
05-20-2006 13:26
Ahhh, okay, I'm not losing my mind then. That's comforting. Annoying, though, that I'm working on this fairly complicated vehicle with complex prim animations and if/when they fix this bug I'm going to have to go back through and rewrite the rotation code. Ah well ... guess I'll be sure to put all rotations in an easily-accessible function at the top of the scripts, so I can just go back and mod that one line of code. Sigh.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
05-20-2006 15:40
LL needs to impelement PRIM_LOCAL_ROTATION (changing the behavior of PRIM_ROTATION would be bad).
_____________________
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
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
05-21-2006 09:28
From: Sinavestos Dassin
Ahhh, okay, I'm not losing my mind then. That's comforting. Annoying, though, that I'm working on this fairly complicated vehicle with complex prim animations and if/when they fix this bug I'm going to have to go back through and rewrite the rotation code. Ah well ... guess I'll be sure to put all rotations in an easily-accessible function at the top of the scripts, so I can just go back and mod that one line of code. Sigh.


Like I said, if you can possibly use llSetLocalRot(), do, because it's not bugged and you wouldn't have to change how you use it if they fix this bug.