Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Trigonometry/Rotation help

Sheridan Otoole
Nomadic Merchant
Join date: 6 Jan 2007
Posts: 9
05-31-2008 14:13
Okay, I've gotten myself into a math tangle that hopefully someone can help me out of. I had hoped this would be a simple action, but I'm not seeing a simple function to do this.

The situation is that I have a simple pointing object, one that orients itself to point directly at an avatar, which most likely will be slightly "down" from its vantage point. Well, using the code at the WIKI (http://rpgstats.com/wiki/index.php?title=LlLookAt), I can get the object to point to the avatar, but I'm currently wanting to use the local X-axis of the object rather than the Z, so am using the code alternative for the llRotLookAt function rather than the llLookAt function.

The problem arises in the fact that often, as the object rotates to point its local X to the avatar target, it barrel rolls around the local X to end up with the local Z no longer pointing up, but off in a random direction. In trying to re-orient this object, I realize that I can't get the local Z axis to point straight up (global Z), if the object itself is tipped in the Y to have it point down. In truth, I need to find out how to orient the object such that the local Z-axis is coplanar to the plane formed by the local X-axis and the global Z-axis.

So, I'm guessing my code will look something like:

CODE

float myAngle = 42;
rotation myAngleRot = llEuler2Rot(<myAngle, 0, 0>); // Rotate around X to un-barrel-roll
rotation newRot = myAngleRot * llGetRot(); // rotate locally, rather than globally
llRotLookAt(newRot, 0.5, 0.5); // Apply the rotation


The question would be, in this scenario, how to find out what "myAngle" should be (I used 42 here as an arbitrary number), since it needs to be the amount that will bring Z back "up" as much as possible.

Or, is it possible to prevent this barrel roll in the first place? I tried setting llSetStatus(STATUS_ROTATE_X,FALSE); before doing the llRotLookAt to begin with, in the hopes of preventing that barrel roll in the first place, but that didn't work. Is there another way?
_____________________
"Any sufficiently advanced technology is indistinguishable from magic" -- Arthur C. Clarke
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
05-31-2008 14:54
You might be able to get away with restricting the rotations, but here's how you can calculate a full rotation using a local coordinate frame. It assumes you want the only deviation from horizontal to be a pitch (local y-axis remains level). The code also doesn't check a couple of corner cases, like the target being AT the prim's position, or being straight up or down from it. Those are left as an exercise for the reader (either to code or search in the forums for where I've already provided such a complete set of logic):

(Note: This has not yet been compiled; a few small syntax fixes might be required.)

CODE

rotation rotationToLookAt(vector targetPos)
{
vector localX = llVecNorm(targetPos-llGetPos());
vector localY = <-localX.y, localX.x, 0.0>; // Same as <0,0,1>%localX
vector localZ = localX%localY;

return llAxes2Rot(localX, localY, localZ);
}
Krista Chaffe
Registered User
Join date: 16 Jun 2007
Posts: 96
05-31-2008 20:14
I spent the last couple of weeks pouring my brain down a similar rat hole
Sheridan Otoole
Nomadic Merchant
Join date: 6 Jan 2007
Posts: 9
06-02-2008 23:48
Aha, the llAxes2Rot function: that was the link I was missing; I think I've got my function worked out just fine now. Thanks Hewee!
_____________________
"Any sufficiently advanced technology is indistinguishable from magic" -- Arthur C. Clarke
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-03-2008 00:47
Sure thing. By the way, I realized that since localX isn't necessarily horizontal, localY technically needs to be normalized too:

CODE

rotation rotationToLookAt(vector targetPos)
{
vector localX = llVecNorm(targetPos-llGetPos());
vector localY = llVecNorm(<-localX.y, localX.x, 0.0>); // Normalized <0,0,1>%localX
vector localZ = localX%localY; // No need for normalization since localX and localY are orthonormal

return llAxes2Rot(localX, localY, localZ);
}