# Preserving up as much as possible while generating a new orientation

This topic is 3854 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi! What I'm trying to do today [smile], is generate an orientation from a normal vector and a desired "up" vector. I want forward (local z axis) to be a normal I have generated off of some world geometry. So far so good. Now, I want up (local y axis) to be as close to possible to some vector, desiredUp. However, the important vector here is the forward vector, so I need the up vector to be "perfectly" perpendicular to the forward vector, just as close to the desiredUp up as possible. (I generate the local x axis via a cross product of the local z and local y.) I'm using quaternions, and need a quaternion for the final orientation. Though if matrices would work better or are needed, I can freely convert between the two. Ideas? So far I've tried just using desiredUp and the normal directly, and that works great when the 2 are perfectly perpendicular. But when things start sloping, it fails (the ground fails, too, for that matter, since desiredUp and the normal would be the same or exactly the opposite): Notice how [1] is aligned well to the wall (which is perpendicular to "up"), but [2] is sort of "upwards"-ish (I tried to outline the quads themselves, they were a bit vague). Thanks a bunch in advance! Hopefully this doesn't sound too stupid [embarrass]

##### Share on other sites
What you want, basically, is to do the same math as is involved in gluLookat. Basically, you're given the forwards vector; you calculate the side vector by a cross product and a normalization; and then you calculate the local up vector by another cross product.

##### Share on other sites
Quote:
 Original post by SneftelWhat you want, basically, is to do the same math as is involved in gluLookat. Basically, you're given the forwards vector; you calculate the side vector by a cross product and a normalization; and then you calculate the local up vector by another cross product.

That was my other approach, but while the generated vectors would work, the y axis would sometimes be completely different from my "desired" y axis. The idea is that my quad should be aligned so that it's "up" is as close as possible to the player's "up" (and not to the side of it, or upside down, for example, since those are all possible given one forward vector). Thanks for the reply, though [smile]!

##### Share on other sites
Quote:
Original post by agi_shi
Quote:
 Original post by SneftelWhat you want, basically, is to do the same math as is involved in gluLookat. Basically, you're given the forwards vector; you calculate the side vector by a cross product and a normalization; and then you calculate the local up vector by another cross product.

That was my other approach, but while the generated vectors would work, the y axis would sometimes be completely different from my "desired" y axis. The idea is that my quad should be aligned so that it's "up" is as close as possible to the player's "up" (and not to the side of it, or upside down, for example, since those are all possible given one forward vector). Thanks for the reply, though [smile]!

Then you did it wrong. With this formulation, the local up-vector will be as close to the desired up-vector as possible while still being perpendicular to the forwards-vector.

##### Share on other sites
Quote:
Original post by Sneftel
Quote:
Original post by agi_shi
Quote:
 Original post by SneftelWhat you want, basically, is to do the same math as is involved in gluLookat. Basically, you're given the forwards vector; you calculate the side vector by a cross product and a normalization; and then you calculate the local up vector by another cross product.

That was my other approach, but while the generated vectors would work, the y axis would sometimes be completely different from my "desired" y axis. The idea is that my quad should be aligned so that it's "up" is as close as possible to the player's "up" (and not to the side of it, or upside down, for example, since those are all possible given one forward vector). Thanks for the reply, though [smile]!

Then you did it wrong. With this formulation, the local up-vector will be as close to the desired up-vector as possible while still being perpendicular to the forwards-vector.

orly?
xa = za.crossProduct(desiredUp), xa.normalise();ya = za.crossProduct(xa); ya.normalise();

Mind giving a bit of a better description? Math confuses me, especially when written in a really ugly font like most math sites do it.

##### Share on other sites
Quote:
 Original post by agi_shixa = za.crossProduct(desiredUp), xa.normalise();ya = za.crossProduct(xa); ya.normalise();

You switched the operands to the cross products. Oh, and there's no real need for the last normalize.

##### Share on other sites
Quote:
Original post by Sneftel
Quote:
 Original post by agi_shixa = za.crossProduct(desiredUp), xa.normalise();ya = za.crossProduct(xa); ya.normalise();

You switched the operands to the cross products. Oh, and there's no real need for the last normalize.

I ... switched the operands to the cross-products? As in I should use xa.crossProduct(za) instead of za.crossProduct(xa)?

##### Share on other sites
Yep, and the same with the other one. Remember that vector cross-products aren't commutative.

##### Share on other sites
Quote:
 Original post by SneftelYep, and the same with the other one. Remember that vector cross-products aren't commutative.

xa = desiredUp.crossProduct(za), xa.normalise();ya = xa.crossProduct(za);

##### Share on other sites
Not sure what you mean by that. What values are you passing in for za and desiredUp, what values are you getting out, and what do you expect to get out? In this situation, numbers are far more reliable than pictures.

• 10
• 40
• 15
• 10
• 23