Maths classes
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Maths classes
Quaternion's default constructor fills it with 1,0,0,0 (identity) but vector and matrix classes leave themselves uninitialised.
A lot of functions in the Quaternion and Matrix classes use pascal notation (functions start with upper case) instead of Ogre's standard of camel notation for functions (and pascal for classes).
Some functions have differing names to the other classes:
Dot product:
Quaternion::Dot()
Vector3::dotProduct()
Squared magnitude:
Quaternion::Norm()
Vector3::squaredLength()
Magnitude:
Vector3::length()
Quaternion has none, you need to do sqrt(Norm())
Angle/Axis conversion:
Quaternion::FromAngleAxis (const Radian& rfAngle, const Vector3& rkAxis)
Matrix3::FromAxisAngle (const Vector3& rkAxis, const Radian& fRadians)
Quaternion::ToAngleAxis (Radian& rfAngle, Vector3& rkAxis)
Matrix3::ToAxisAngle (Vector3& rkAxis, Radian& rfAngle)
Determinant:
Matrix3::Determinant()
Matrix4::determinant()
Inverse:
Matrix3::Inverse()
Matrix4::inverse()
Quaternion::Inverse()
Matrix3 also has another Inverse() function which takes a Matrix3 and returns a bool if the arg is the inverse of the current. This doesn't exist in Matrix4 or Quaternion, and should be called something like isInverse().
Quaternion and Vector3 have isNan() to check values for nans. Matrix3 and Matrix4 are missing it.
Quaternion is missing the normalisedCopy() from the vector classes.
Most methods in Matrix4 are inlined in the header, but the same functions (operator overloads, etc) are in the cpp for Matrix3.
Vector4 is lacking a lot of Vector3's methods and constants (like UNIT_X, length(), normalise(), distance(), etc). Although ogre's Vector4 class is really only intended for use with homogeneous vectors instead of generic 4d vectors, so that's probably for the best.
Matrix4::getTrans() returns the current translation, Matrix4::getScale makes a new scale matrix and returns that instead of returning the current scale. There is also a second Matrix4::getTrans() which is a static function for making a translation matrix.
Matrix4::makeTrans() overwrites the current matrix with a pure translation matrix, but there's no makeScale or makeOrientation (instead you assign a new matrix4 with a quaternion passed to the constructor).
Matrix4::setScale() directly sets the diagonal using a Vector3. This will only work on a matrix with no rotation (comments don't mention that). Calling setScale on a Matrix4 with existing rotations will do freaky stuff (at the least it will make it non orthogonal (skewed)). Really it should be doing something like setting each axis vector in the 3x3 upper corner to the normalised axis vector times the corresponding scale component.
For example if your matrix4 was
1,0,0,0
0,1,0,0
0,0,1,0
0,0,0,1
then setScale(4,5,6) would give you the correct answer of:
4,0,0,0
0,5,0,0
0,0,6,0
0,0,0,1
But if the matrix4 was rotated 90 degrees around the z axis first:
0,-1,0,0
1,0,0,0
0,0,1,0
0,0,0,1
then setScale(4,5,6) would give:
4,-1,0,0
1,5,0,0
0,0,6,0
0,0,0,1
instead of:
0,-5,0,0
4,0,0,0
0,0,6,0
0,0,0,1
Negative scales will confuse those setScale changes, but they confuse everything anyway and should be made illegal or something (I'm looking at you Sketchup!).
Everything I said about Vector3 pretty much applies to Vector2 as well (but not Vector4), they appear to be a copy/paste with the z's removed. Speaking of which, some comments might need fixing in Vector2 because of that. For example, perpendicular() says there are infinite possibilities, but for a 2d vector there's really only 2 possibilities. I haven't checked all the comments, I'm mainly looking at function names.
Also, does anybody think we should have a Matrix2 class? I don't really care either way (the only time in an ogre app I'd use 2d matrices would be in 2d game logic, and I'd do all that with my own math library anyway), but it would make sense since we already have a Vector2 class.
A lot of functions in the Quaternion and Matrix classes use pascal notation (functions start with upper case) instead of Ogre's standard of camel notation for functions (and pascal for classes).
Some functions have differing names to the other classes:
Dot product:
Quaternion::Dot()
Vector3::dotProduct()
Squared magnitude:
Quaternion::Norm()
Vector3::squaredLength()
Magnitude:
Vector3::length()
Quaternion has none, you need to do sqrt(Norm())
Angle/Axis conversion:
Quaternion::FromAngleAxis (const Radian& rfAngle, const Vector3& rkAxis)
Matrix3::FromAxisAngle (const Vector3& rkAxis, const Radian& fRadians)
Quaternion::ToAngleAxis (Radian& rfAngle, Vector3& rkAxis)
Matrix3::ToAxisAngle (Vector3& rkAxis, Radian& rfAngle)
Determinant:
Matrix3::Determinant()
Matrix4::determinant()
Inverse:
Matrix3::Inverse()
Matrix4::inverse()
Quaternion::Inverse()
Matrix3 also has another Inverse() function which takes a Matrix3 and returns a bool if the arg is the inverse of the current. This doesn't exist in Matrix4 or Quaternion, and should be called something like isInverse().
Quaternion and Vector3 have isNan() to check values for nans. Matrix3 and Matrix4 are missing it.
Quaternion is missing the normalisedCopy() from the vector classes.
Most methods in Matrix4 are inlined in the header, but the same functions (operator overloads, etc) are in the cpp for Matrix3.
Vector4 is lacking a lot of Vector3's methods and constants (like UNIT_X, length(), normalise(), distance(), etc). Although ogre's Vector4 class is really only intended for use with homogeneous vectors instead of generic 4d vectors, so that's probably for the best.
Matrix4::getTrans() returns the current translation, Matrix4::getScale makes a new scale matrix and returns that instead of returning the current scale. There is also a second Matrix4::getTrans() which is a static function for making a translation matrix.
Matrix4::makeTrans() overwrites the current matrix with a pure translation matrix, but there's no makeScale or makeOrientation (instead you assign a new matrix4 with a quaternion passed to the constructor).
Matrix4::setScale() directly sets the diagonal using a Vector3. This will only work on a matrix with no rotation (comments don't mention that). Calling setScale on a Matrix4 with existing rotations will do freaky stuff (at the least it will make it non orthogonal (skewed)). Really it should be doing something like setting each axis vector in the 3x3 upper corner to the normalised axis vector times the corresponding scale component.
For example if your matrix4 was
1,0,0,0
0,1,0,0
0,0,1,0
0,0,0,1
then setScale(4,5,6) would give you the correct answer of:
4,0,0,0
0,5,0,0
0,0,6,0
0,0,0,1
But if the matrix4 was rotated 90 degrees around the z axis first:
0,-1,0,0
1,0,0,0
0,0,1,0
0,0,0,1
then setScale(4,5,6) would give:
4,-1,0,0
1,5,0,0
0,0,6,0
0,0,0,1
instead of:
0,-5,0,0
4,0,0,0
0,0,6,0
0,0,0,1
Negative scales will confuse those setScale changes, but they confuse everything anyway and should be made illegal or something (I'm looking at you Sketchup!).
Everything I said about Vector3 pretty much applies to Vector2 as well (but not Vector4), they appear to be a copy/paste with the z's removed. Speaking of which, some comments might need fixing in Vector2 because of that. For example, perpendicular() says there are infinite possibilities, but for a 2d vector there's really only 2 possibilities. I haven't checked all the comments, I'm mainly looking at function names.
Also, does anybody think we should have a Matrix2 class? I don't really care either way (the only time in an ogre app I'd use 2d matrices would be in 2d game logic, and I'd do all that with my own math library anyway), but it would make sense since we already have a Vector2 class.
-
- OGRE Moderator
- Posts: 3447
- Joined: Mon Jul 18, 2005 4:15 pm
- Location: Wales, UK
- x 58
Re: Maths classes
That is a good list. I've always thought that the Maths classes all though brilliant that they are, need a good comb through to make everything consistent.
I also think there should be a template as/from functions to convert to different types, and I've always thought that the Matrix4::getTrans(), makeTrans(), setScale() functions have been confusing as well.
I also think there should be a template as/from functions to convert to different types, and I've always thought that the Matrix4::getTrans(), makeTrans(), setScale() functions have been confusing as well.
-
- OGRE Expert User
- Posts: 1671
- Joined: Mon Jan 21, 2008 10:26 pm
- x 50
Re: Maths classes
I agree. Concerning the Matrix2, I also don't find it necessary at the moment.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
-
- OGRE Team Member
- Posts: 5476
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1359
Re: Maths classes
I agree it's a bit of a mess.
About the constructor not filling the variables is controversial, as it is performance sensitive.
Compilers can take them away, but not always. A big example is std::vector::resize()
It has already discussed in another thread and I'm inclined towards treating MatrixN Quaternions and Vectors as plain data types (like float or int)
About the constructor not filling the variables is controversial, as it is performance sensitive.
Compilers can take them away, but not always. A big example is std::vector::resize()
It has already discussed in another thread and I'm inclined towards treating MatrixN Quaternions and Vectors as plain data types (like float or int)
-
- Gnome
- Posts: 397
- Joined: Sat Nov 08, 2008 1:59 pm
- x 2
Re: Maths classes
I think Matrix2 could be quite useful for compositors... pass a Matrix2 parameter that transforms [0,1] coordinates to some useful space.madmarx wrote:I agree. Concerning the Matrix2, I also don't find it necessary at the moment.
That assumes shaders understand 2x2 matrices, do they?
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Maths classes
Shaders do support float2x2. You can use it to mess around with uv coords (rotate and scale textures).
Hmm, seems this hasn't gone far. I just started my holidays, so I might see if I can whip up a patch (in between playing skyrim and X3 Albion Prelude, which will be most of my time).
Hmm, seems this hasn't gone far. I just started my holidays, so I might see if I can whip up a patch (in between playing skyrim and X3 Albion Prelude, which will be most of my time).
-
- OGRE Community Helper
- Posts: 767
- Joined: Wed Oct 10, 2007 2:36 pm
- Location: Germany
- x 39
Re: Maths classes
Kojack, good proposal for the math function names.
I came to the papercut section, because of your Euler Angle Class, which you published in the wiki. Now I see that you still created a math topic.
I wanted to tell you my idea to integrate the Euler Angle Class to the official Ogre souce code.
If the developers agree, the comments should be "marked up" in a way so that the Ogre documentation creator tool can grabb them.
I came to the papercut section, because of your Euler Angle Class, which you published in the wiki. Now I see that you still created a math topic.
I wanted to tell you my idea to integrate the Euler Angle Class to the official Ogre souce code.
If the developers agree, the comments should be "marked up" in a way so that the Ogre documentation creator tool can grabb them.
Help to add information to the wiki. Also tiny edits will let it grow ... 
Add your country to your profile ... it's interesting to know from where of the world you are.

Add your country to your profile ... it's interesting to know from where of the world you are.
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Maths classes
I actually have a new version of the euler class, much better, more tested and now compatible with ogre's angles (mine was a crazy combination of left handed and right handed angles, with some wrapping around and some unlimited. Now it's better). I haven't uploaded to the wiki yet, since I hacked one major function and haven't tested it yet.
I've got a cool test where the euler class controls the head of the sinbad model to do object tracking with angular limits and slow turning, regardless of the orientation of the original mesh. It's creepy watching him look at the camera.
I've also started working on a c# version for mogre.
I think integrating it was mentioned before and rejected. It's pretty small and header only, so pasting from the wiki is fine for most people.
I implemented most of the changes in this thread to ogre, but I haven't submitted a patch because it breaks so many files, plus probably a heap of wiki pages. I still think it should be done, but not with ogre 1.8 already at rc1. It would be better to start fresh with 1.9. I'll submit a patch once then (once I work out how to do patches in mercurial). This could coincide with the frequently requested plan to separate the ogre maths code into a library, so people can use it in servers or other apps without all the other ogre stuff.
Good point on the comments format, I should get into the habit of that.
I've got a cool test where the euler class controls the head of the sinbad model to do object tracking with angular limits and slow turning, regardless of the orientation of the original mesh. It's creepy watching him look at the camera.

I've also started working on a c# version for mogre.
I think integrating it was mentioned before and rejected. It's pretty small and header only, so pasting from the wiki is fine for most people.
I implemented most of the changes in this thread to ogre, but I haven't submitted a patch because it breaks so many files, plus probably a heap of wiki pages. I still think it should be done, but not with ogre 1.8 already at rc1. It would be better to start fresh with 1.9. I'll submit a patch once then (once I work out how to do patches in mercurial). This could coincide with the frequently requested plan to separate the ogre maths code into a library, so people can use it in servers or other apps without all the other ogre stuff.
Good point on the comments format, I should get into the habit of that.
-
- OGRE Community Helper
- Posts: 767
- Joined: Wed Oct 10, 2007 2:36 pm
- Location: Germany
- x 39
Re: Maths classes
Nice to know. Please keep it in mind to publish it.Kojack wrote:I actually have a new version of the euler class
I will wait for your notice by suscription of this topic.

Oh, interesting. Do you use Mogre, too?Kojack wrote:I've also started working on a c# version for mogre.
If not, what's your motivation to do the extra work?
I thought, it would be a useful extension for the Ogre.Math class. And it doesn't blow up the Ogre code, because it has only "a few" lines of code.Kojack wrote:I think integrating it was mentioned before and rejected.
But this is only my personal opinion.
One way could be:I implemented most of the changes [...] it breaks so many files, plus probably a heap of wiki pages.
Keep the old API functions and add an obsolete note to the description.
Parallel to that add the new functions.
On the other hand the redundancy would blow up the API a little bit and perhaps confuse people which only looks to API members in Visual Studio without reading the description.
You are right in the point that there should not be API changes after release of RC1.
For the wiki pages I don't care too much.
We can search for all related pages by google "site:ogre3d.org tiki <functionName>".
Then we can update the code snippets and add a note for usage with previous Ogre version.
Also there is information about in the Changelog. When somebody search for an "unknown method", he will find the changelog.
It's some extra work for developers, but they have good chances to manage it.
Help to add information to the wiki. Also tiny edits will let it grow ... 
Add your country to your profile ... it's interesting to know from where of the world you are.

Add your country to your profile ... it's interesting to know from where of the world you are.
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Maths classes
I use mogre around the middle of every year. I have a rapid app dev class which teaches c#, then we use mogre to make game level editors and stuff.
I thought it would be handy, and a bit of c# practice.
(Plus when searching for euler on the wiki, your scratchpad shows up, saying you had plans to port the euler class. So I knew there was an audience for a c# version of the new one)
You should have seen the trouble I had getting ogre recorded into animated gifs (of euler stuff).
Virtual Dub can take image sequences and save them as a gif, but only firefox can display them, every other image program says the gif is corrupt.
I thought it would be handy, and a bit of c# practice.
(Plus when searching for euler on the wiki, your scratchpad shows up, saying you had plans to port the euler class. So I knew there was an audience for a c# version of the new one)

You should have seen the trouble I had getting ogre recorded into animated gifs (of euler stuff).

-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Maths classes
Ok, I got off my ass and updated the wiki.
New euler class is up at http://www.ogre3d.org/tikiwiki/tiki-ind ... ef_id=1114
It's now fully compatible with Ogre::Matrix3::FromEulerAnglesYXZ and Ogre::Matrix3::ToEulerAnglesYXZ (note: only the YXZ versions, because my class is based purely on Yaw Pitch Roll ordering, which is most convenient for upright character controllers and cameras).
(My previous class was made to be easy, so I used clockwise for positive yaw to match compass headings. But the rest of ogre uses the standard anticlockwise right handed rotation for yaw. Now mine matches ogre).
New euler class is up at http://www.ogre3d.org/tikiwiki/tiki-ind ... ef_id=1114
It's now fully compatible with Ogre::Matrix3::FromEulerAnglesYXZ and Ogre::Matrix3::ToEulerAnglesYXZ (note: only the YXZ versions, because my class is based purely on Yaw Pitch Roll ordering, which is most convenient for upright character controllers and cameras).
(My previous class was made to be easy, so I used clockwise for positive yaw to match compass headings. But the rest of ogre uses the standard anticlockwise right handed rotation for yaw. Now mine matches ogre).
-
- OGRE Community Helper
- Posts: 767
- Joined: Wed Oct 10, 2007 2:36 pm
- Location: Germany
- x 39
Re: Maths classes
This sounds great!!Kojack wrote: I use mogre around the middle of every year. I have a rapid app dev class which teaches c#, then we use mogre to make game level editors and stuff.
I would like to be your student.

Very very nice !!Ok, I got off my ass and updated the wiki.

Thank you so much.
I wanted to publish an announcement in the Mogre forum.
But then I recognized that your new class would have problems with the unfixed Mogre bug. (As we talked about some months ago.)
Your old class should work even with the bug, because it doesn't touches the buggy properties (get: Quaternion.Yaw/.Pitch/.Roll).
Details related to the bugs are here:
http://www.ogre3d.org/addonforums/viewt ... 017#p98017
...... Start to read the post at section "Also important".
My preparated announcement is here: (if you are interested to read)
http://www.ogre3d.org/addonforums/viewt ... 048#p98048
Help to add information to the wiki. Also tiny edits will let it grow ... 
Add your country to your profile ... it's interesting to know from where of the world you are.

Add your country to your profile ... it's interesting to know from where of the world you are.
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Maths classes
I tried to get my one to match the quaternion's yaw/pitch/roll methods (generate a quaternion from the euler, then read the quat back into a second euler and see how they compare). It didn't go well.
But what works much better than reading the angles from a quaternion directly is to convert the quaternion to a 3x3 matrix, then call ToEulerAnglesYXZ on it. That returns them in the way I was expecting.
The quaternion code is using a different angle combination than what I wanted. That may also cause some of the confusion people have had with it.
But what works much better than reading the angles from a quaternion directly is to convert the quaternion to a 3x3 matrix, then call ToEulerAnglesYXZ on it. That returns them in the way I was expecting.
The quaternion code is using a different angle combination than what I wanted. That may also cause some of the confusion people have had with it.
-
- OGRE Community Helper
- Posts: 767
- Joined: Wed Oct 10, 2007 2:36 pm
- Location: Germany
- x 39
Re: Maths classes
Mogre returns values related to other co-domains and in special cases even NaN values.
Source of the problems is that currently Mogre uses System.Math instead of Ogre.Math.
I quote yourself:
I hope the problems will be fixed soon.
Source of the problems is that currently Mogre uses System.Math instead of Ogre.Math.
I quote yourself:
The related discussion was in topic Quaternion::getYaw() returns NaN (not defined)Kojack wrote:Does Mogre use Ogre's math code for quaternions? I think it used it's own vector math instead of wrapping ogre's for performance.
If so, it might not have the same protection.
getYaw does an asin operation. This MUST be given a value between -1 to 1. Outside of that range will cause a nan. Even slight floating point errors like 1.000001 will fail. Ogre provides Math::ASin, which protects asin from being called with bad values. The Ogre getYaw function calls Math::ASin, but maybe the Mogre getYaw is doing asin directly.
That's the only operation in there that could cause a nan, assuming that the quaternion didn't contain a nan to start with.
There are problems with the getYaw and related functions though. I was testing them a few days ago (while making a new version of my Euler class) and I found that the returned values are wrong in many cases. Not just the usual thing where several different combination of eulers result in the same quaternion, this was giving results that were mirrored along the x or y axes. Converting the quaternion to a matrix3, then calling one of the toeuler methods gave the correct results.
The discussion was in topic co-domains of Quaternion::getYaw(), getPitch() and getRoll()Kojack wrote:Mogre using System::Math::Asin is definitely the cause of the nans.
Asin can only accept numbers in the range -1 to 1. Anything outside that range is mathematically impossible and meaningless. Due to floating point error, the result of -2*(x*z-w*y) could end up being slightly off, such as 1.000001 or -1.000001. That is enough to make Asin (and Acos) fail. Ogre has protection against this, it checks the value before calling asin. Mogre should do this too if it isn't going to call the ogre version.
I hope the problems will be fixed soon.
Help to add information to the wiki. Also tiny edits will let it grow ... 
Add your country to your profile ... it's interesting to know from where of the world you are.

Add your country to your profile ... it's interesting to know from where of the world you are.
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Maths classes
I didn't mean the nan stuff, I remember that. The problems with the quaternion code that I had were different, due to euler ordering. There's 6 valid orders, I used one and ogre wanted another, causing the object to sometimes freak out and flip around the wrong axis (not instant flip, it was smooth). The matrix 3 class gives you the option of using any of the 6 orderings manually, while the quaternion class is hard coded to just one ordering. It's not really a problem because a major point of the euler class was to not read values back from a quaternion.
-
- OGRE Community Helper
- Posts: 767
- Joined: Wed Oct 10, 2007 2:36 pm
- Location: Germany
- x 39
Re: Maths classes
Do you mean the common behaviour or the special Mogre behaviour?Kojack wrote:I didn't mean the nan stuff, I remember that. [...] causing the object to sometimes freak out and flip around the wrong axis
For the second case:
They are different, because of the bug, which causes other co-domains for the returned Euler values.
With the Mogre but, the returned Yaw value has a co-domain of -90..90.
If the Yaw rotation is out of this range, the scene node is upside down.
Yes, but only when the user understands the related math.Kojack wrote:The matrix 3 class gives you the option of using any of the 6 orderings manually

In the past I tried to write code, which converts a quaternion state to euler angles. It worked for the Yaw angle, but then I gave up, because I stent too much time to understand the needed math basics.Kojack wrote:It's not really a problem because a major point of the euler class was to not read values back from a quaternion.
My alternative plan was to "cache" the euler values. Your Euler class will do the job well. Additionally it has extra functionality.
A converter to read values back from quaternions would be still useful, too.
Example 1: Get "world related" (derived) Euler angles of a SceneNode, which is clamped to an other SceneNode.
Example 2: Get Euler angles of SceneNodes, which were moved by a physics library.
Well, this is just a side note.
Perhaps there still exists relating solutions in other game/3D developer forums.
Help to add information to the wiki. Also tiny edits will let it grow ... 
Add your country to your profile ... it's interesting to know from where of the world you are.

Add your country to your profile ... it's interesting to know from where of the world you are.
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Maths classes
I'm just talking about general ogre behaviour.
Here's a video showing the issue:
[youtube]-boq7NPi1m8[/youtube]
The right sinbad uses a euler object with keyboard control (he also has head tracking on, but that's not important here). The euler object is used to set his orientation quaternion.
The middle sinbad reads the right sinbad's orientation (as a quaternion), calls getYaw, getPitch and getRoll on it, puts them into a second euler object and uses it as the orientation.
The left sinbad reads the right sinbad's orientation as well, but it converts the orientation quaternion into a matrix, then uses the matrix ToEulerAnglesYXZ to get the yaw, pitch and roll and puts them in a third euler object and then use that for orientation.
As you can see, the left and right ones are identical. The problem is that the rotation order for getYaw, getPitch and getRoll doesn't match my euler code. But matrices let you choose, so I just picked the correct one.
Different combinations can be chosen based on coordinate system (does yaw go around the y or z axis?) and gimbal lock. When the second angle is 90 or -90 degrees, the first and third angles gimbal lock. So in mine if you look up (pitch), the yaw and roll gimbal lock. If looking up is common, a different ordering would move the gimbal lock to a less important angle.
I'm pretty sure this is also why you were getting yaw in the +/-90 range. If you don't want to flip upside down (or sideways, or whatever), the first angle in the euler combination is usually used with a 360 degree range, while the second only has a 180 degree range (so a camera could look around 360 degrees, but usually you don't pitch it until it's upside down to look behind yourself). Ogre's quaternions don't use yaw/pitch/roll order, so yaw isn't the first angle so it isn't considered the primary one you rotate to face a direction.
To bypass the range issue, instead of this:
you can do this:
Here's a video showing the issue:
[youtube]-boq7NPi1m8[/youtube]
The right sinbad uses a euler object with keyboard control (he also has head tracking on, but that's not important here). The euler object is used to set his orientation quaternion.
The middle sinbad reads the right sinbad's orientation (as a quaternion), calls getYaw, getPitch and getRoll on it, puts them into a second euler object and uses it as the orientation.
The left sinbad reads the right sinbad's orientation as well, but it converts the orientation quaternion into a matrix, then uses the matrix ToEulerAnglesYXZ to get the yaw, pitch and roll and puts them in a third euler object and then use that for orientation.
As you can see, the left and right ones are identical. The problem is that the rotation order for getYaw, getPitch and getRoll doesn't match my euler code. But matrices let you choose, so I just picked the correct one.
Different combinations can be chosen based on coordinate system (does yaw go around the y or z axis?) and gimbal lock. When the second angle is 90 or -90 degrees, the first and third angles gimbal lock. So in mine if you look up (pitch), the yaw and roll gimbal lock. If looking up is common, a different ordering would move the gimbal lock to a less important angle.
I'm pretty sure this is also why you were getting yaw in the +/-90 range. If you don't want to flip upside down (or sideways, or whatever), the first angle in the euler combination is usually used with a 360 degree range, while the second only has a 180 degree range (so a camera could look around 360 degrees, but usually you don't pitch it until it's upside down to look behind yourself). Ogre's quaternions don't use yaw/pitch/roll order, so yaw isn't the first angle so it isn't considered the primary one you rotate to face a direction.
To bypass the range issue, instead of this:
Code: Select all
Quaternion q = node->getOrientation();
Radian yaw = q.getYaw();
Radian pitch = q.getPitch();
Radian roll = q.getRoll();
Code: Select all
Quaternion q = node->getOrientation();
Radian yaw;
Radian pitch;
Radian roll;
Matrix3 m;
q.ToRotationMatrix(m);
m.ToEulerAnglesYXZ(yaw,pitch,roll);
-
- OGRE Community Helper
- Posts: 767
- Joined: Wed Oct 10, 2007 2:36 pm
- Location: Germany
- x 39
Re: Maths classes
Thanks for your comprehensive explanation and creating the video, which is a good demonstration.
I want to put a copy into the wiki. So others can find it at a much more common place. (this topic is very hidden)
In the past I couldn't figure out the sense and usage of functions like ToEulerAnglesYXZ(...).
One year ago I created the topic Add description of class members to Ogre class reference.
There I listed several undocumented class members.
For some of them are proposed descriptions in the topic.
It would need just copy and paste for a core code administrator.
Unfortunately in the current Ogre documentation (online) I don't see any change.
Without documentation it's hard to figure out how to do something.
Well, I don't want to hit you with quotes.
I want to put a copy into the wiki. So others can find it at a much more common place. (this topic is very hidden)
Very good to know.Kojack wrote:you can do this:
Code: Select all
Quaternion q = node->getOrientation(); Radian yaw; Radian pitch; Radian roll; Matrix3 m; q.ToRotationMatrix(m); m.ToEulerAnglesYXZ(yaw,pitch,roll);
In the past I couldn't figure out the sense and usage of functions like ToEulerAnglesYXZ(...).
One year ago I created the topic Add description of class members to Ogre class reference.
There I listed several undocumented class members.
For some of them are proposed descriptions in the topic.
It would need just copy and paste for a core code administrator.
Unfortunately in the current Ogre documentation (online) I don't see any change.

Without documentation it's hard to figure out how to do something.
I just quote yourself as posted here in March 2011:Kojack wrote:I'm pretty sure this is also why you were getting yaw in the +/-90 range.
In comparison to that Mogre returns:Kojack wrote:getYaw() is -180 to 180. I just tested it and it returned values below -90 and above 90 fine.
Code: Select all
getYaw -90 .. 90
getPitch -180 .. 180
getRoll -180 .. 180
Help to add information to the wiki. Also tiny edits will let it grow ... 
Add your country to your profile ... it's interesting to know from where of the world you are.

Add your country to your profile ... it's interesting to know from where of the world you are.
-
- OGRE Community Helper
- Posts: 767
- Joined: Wed Oct 10, 2007 2:36 pm
- Location: Germany
- x 39
Re: Maths classes
By your useful code snippet I created a second constructor for the C# version of your class:Kojack wrote: you can do this:
Code: Select all
Quaternion q = node->getOrientation(); Radian yaw; Radian pitch; Radian roll; Matrix3 m; q.ToRotationMatrix(m); m.ToEulerAnglesYXZ(yaw,pitch,roll);
Code: Select all
/// <summary>
/// Constructor which calculates the Euler Angles from a quaternion.
/// </summary>
public Euler(Quaternion oriantation)
{
Matrix3 rotMat;
rotMat = oriantation.ToRotationMatrix();
rotMat.ToEulerAnglesYXZ(out mYaw, out mPitch, out mRoll);
mChanged = true;
mCachedQuaternion = Quaternion.IDENTITY;
}
Just to let you know about the further benefit of your work.

Help to add information to the wiki. Also tiny edits will let it grow ... 
Add your country to your profile ... it's interesting to know from where of the world you are.

Add your country to your profile ... it's interesting to know from where of the world you are.