Home › Technical Talk
# How do you accurately calculate eularAngles to avoid flipped orientation?

One of my tools exports scenes/objects into a game engine. One of the problems I have encountered lately is that sometimes the orientation is incorrect. The engine requires eulerAngles
but sometimes the angles are simply flipped.

In the attached image, the Max scene is the original. The right is the exported scene in another program called Hammer. Notice that all of the teapots along the yellow hilight are inverted on multiple axises in the game editor.

I normally havent had a problem with this by just using something like:

But when I started experimenting with painting models in the scene with the Object Paint tools, Ive found that this method of calculating is incorrect. As you can see, those I simply copied, moved and rotated exported correctly--but all those part of an object paint stroke (yellow hilight) have inaccurate rotations.

The questions:

1) How do I detect this incorrect orientation?

2) How do I resolve it? (Ive tried multiplying the angles by -1 or subtracting 180 in various attempts to get at the issue but Im not getting the desired results).

Again, like always, all help is appreciated.
## Leave a Comment

- Offline / Send Message
- Joined
- 49 Topics
- 184 Replies

In the attached image, the Max scene is the original. The right is the exported scene in another program called Hammer. Notice that all of the teapots along the yellow hilight are inverted on multiple axises in the game editor.

I normally havent had a problem with this by just using something like:

local theRotation = theModel.rotation as eulerAngles

But when I started experimenting with painting models in the scene with the Object Paint tools, Ive found that this method of calculating is incorrect. As you can see, those I simply copied, moved and rotated exported correctly--but all those part of an object paint stroke (yellow hilight) have inaccurate rotations.

The questions:

1) How do I detect this incorrect orientation?

2) How do I resolve it? (Ive tried multiplying the angles by -1 or subtracting 180 in various attempts to get at the issue but Im not getting the desired results).

Again, like always, all help is appreciated.

## Replies

Developer of:

1: probably impossible unless you make some fairly big assumptions

2: see above

With animation...

1.look for big changes in curves over short spaces of time(<1frame)

2. now it gets complicated....

What are you actually trying to get out at the end?

Could you just reset transforms on the painted objects?

i would try to isolate one simple object that has the problem and try to reproduce it. make sure that it is actually the sort of flipping you think it is then try to fix it.

if there is a mis-match of axis or inverted rotation you should be able to find it by applying the (worldspase) transformation matrices to a axis-aligned object at the origin.

edit:

as poopipe noted this could take some work to track down. not so simple.

it looks like it could be an inverse scale. i have no idea how these transforms are applied so its not really possible to comment past simple observation.

edit:

if you are trying to match an object from one coordinate system to another. ie from one software to another or file etc, apply the same transformations from one to the other system. take into account any differences ie y is up x is up etc. any other solution will probably be complicated as poopipe noted.

i have not looked through this whole pdf but it seems to be at the right level of detail to solve your problem.

http://gregslabaugh.name/publications/euler.pdf

also you might want to look at a computer graphics book or opengl for transform matrices.

In the end I am simply trying to get a model to export at the same rotation it is in Max to the game engine. The methods I've successfully been using are getting just $object.rotation or $object.transform.rotation ... and that always works when I manually place/rotate the objects.

The problem seems to only occur when I'm painting the objects into the scene with Object Paint ... and this creates rotations that "looK" the same as they would look if I manually placed/rotated... but the output rotation doesn't match.

I had played with Reset Xform as I suspected that would fix it... but so far that didn't work... but that may be a result of the Paint Objects being Instances or References of the original object; I'll test later when I can open Max again.

Developer of:

i don't think that would work. reset xform aligns your object space axis to the world space axis. i'm not sure how that would help you unless of course you do not want to keep the object rotations and translations.

but it look like your problem is not with the rotation in general but with some modifier that is changing the transform matrix in some way. so it should be much easier then dealing with eular angles. :thumbup: you simply have to figure out how to strip those modifications out to the point where you have an 'unmolested' object transform that can be read by whatever is exporting your geometry.

note:

i note here that i have for the first time found a use for the word unmolested in proper context. and aword myself 2 points.

Developer of:

You are right. It turns out that the scale on the painted objects is [-1,-1,-1] . Now I can get somewhere. Though honestly, I'm scratching my head trying to figure out the best way to negate the negative scale to get the correct rotation info based on this.

Ideas? Hints?

Again, thank you all.

Developer of:

If you negate the quaternion that is rotating around the longest path, you obtain the shortest path and vice versa.

Regarding the negative scale, I know it must be the culprit...

I figure there must be some fomula to multiply the PRS matrix such that the orientation will output correctly, but I haven't figured it out. I noticed that when, in Max, I select an object and type $.scale = [1,1,1] it will suddenly orient the same as the erroneous models in the export.

Sorry about my ignorance... I've been on a long process of learn as you go and have no formal education on anything--who didn't even graduate high school. (I'm a shoot-from-the-hip programmer that doesn't always have the luxury of training beyond docs and the kindness of the community ) ANd all things math are my worst skills... so it's always a slow process for me to figure out anything dealing with matrix math.

Developer of:

Controller:Position_Rotation_Scale

Developer of:

What's the world up axis of 3dsmax vs Hammer and are they left/right handed coordinates?

model orientationis in what Max would have as YZX but otherwise forworld geoemtryit is all XYZ with Z up .Developer of:

that would just be an elementary inverse scale matrix. 'math speak' which is essentially just a multiply of a channel by a negative number.

edit:

see below.

hey i missed this post when i was skimming the thread. if the effected object has a scale of (-1,-1,-1) then thats really simple to fix. just multiply each scale transform buy -1 ie -1*(-1,-1,-1) and that should give you the correct result.

the scale and rotation are independent. you don't need to mess with rotation.

I'll probably return to this to create a workflow that solves it mathematically when I have more time to devote to it. For the moment, the helper functions are usable and almost always solve the problem.

I guess I'd not even have to deal with this if the Object Paint tools would give positive scales to begin with... like you'd expect

Developer of:

on a side note if you wanted to do the scale on paper you would first have to translate the pivot to the origin.

then rotate to axis align the coordinate system

then apply the scale by -1

then do the inverse rotate and translate to put the object back into place.

its a pain is the ass. i figured that maybe the objects would be smart enough to just do a -1*scale but i guess not. sorry mate. but i do think you should be able to get it with a scale done in the right way given your scale is -1,-1,-1. just makes sense. but who knows could be something else entirely.

i would pick up a used intro to linear algebra book for cheap on amazon that has a matrix algebra chapter if you want to figure the correct math. that should be more then enough to get you out of any transform matrix math problems. Larson, Strang or Lay are good.

i have heard this was a good one from a mathematics professor but have not personally read it. http://joshua.smcvt.edu/linearalgebra/

Unfortunately, I'm in and out of the hospital with a family illness ... and now away from Max tonight. So I cannot give the exact code I have where the problem lies. But here is a little clearer overview.

A collection of objects in the scene (say 100 teapots that are references of one particular teapot). 50 of them were simply Referenced manually with Shift+Drag. But the other 49 were created with the Object Paint tool .

Visually, all the teapots are oriented nicely (however that may be for the scene). But when you go to extract the XYZ orientation for another program, the values are all wrong for the 49 teapots that were made with the Paint tool. As it turns out, the only significant difference between these 49 teapots and the 51 (50 refs plus original) is that the originals have a scale of [1,1,1] and the painted ones have [-1,-1,-1].

So in the end the best thing would be some function that looks like this applied to the objects :

My guess is that this code already exists out there... but I am not quite the Google Master I used to be. Anymore, half the time I'm looking for the answer to something I keep finding my own posts presenting the problems!

But yes I may need to start learning to integrate matrix math into my book of knowledge no matter how much it makes me moan... otherwise I will keep filling up the forums with questions

Developer of:

In the meantime, any more feedback is appreciated.

Developer of:

I hope it helps someone.

Essentially, if you need to have a scale of [1,1,1] on your objects that were painted with the Object Paint tool, you can select those objects and then do something like this:

I'll be putting this into a function in Wall Worm in the next week.

PS. If someone has a more robust formula, I'd be happy to see it... all the linear algebra stuff is making my beard get too gray too fast.

Developer of:

$scale = `abs $scale`;

Abs, absolute value, returns a non-negative value.

-1 is a special case which gives the inverse.

@shawnolson

so i took a look at that pdf and i'm going to have to say its crap for learning simple matrix algebra in order to understand 3d matrix transforms. its intended for math majors who need to learn rigorous proofs and will go on to abstract algebra etc. thats absolutely not what you need to read. those other books are much better. or any standard 'engineering' intro to linear algebra book. you only need the first few chapters on Gaussian elimination and matrix algebra you don't need to read the whole thing.

that pdf will probably only annoy you with unimaginably abusive mathematical rigor. :poly142: matrix algebra is quite easy if you get the right book tho.

Well you must know my type quite well :P I started reading it and lost all the zest for solving the problem after a few pages! I really wish I would have sucked it up and learned more math back in school... but honestly it's the one realm that my brain turns into a grinder when pondering. Logic, I'm great. Syntax, programming, writing, analyzing, yada yada yada... I excel with ease. But math... it likes my brain as much as I like Glenn Beck.

What annoys me is that I can't just plug my brain into some machine and learn everything; and I know that this "problem" is probably a very novice mathematical problem. But now that I have a solution to my current scenario... I may never solve it.

Incidentally, the code needs an addition because it seems that the UVW seems to flip too... so that needs to be accounted for if anyone else comes across this. I'll post that solution tomorrow if I get time.

Developer of:

value = abs(value)

It's really not that difficult, I just got an example script off the net (Snap2Object.ms by P.G.Preeth). That way you have full control over the transforms of the placed objects.

Developer of:

Using abs() wouldn't help because the scale and rotation are linked mathematically (in the transform). Just getting the positive scale values was never really the issue since it was the rotations that I needed.

Reset XForm was my first step in figuring it out. But it failed. As Gray noted... Reset XForm aligns the object to the world... and that throws out the window the rotation values I am trying to get . (We all think of using that automatically here because we all know to use Reset Xform to solve random scaling issues... but in this case it isn't a good solution.)

PEN answered this question over on the Area the best so far. I haven't had a chance to open Max and test this in my code... but my guess is that it will work.

Developer of: