So the title says it all. Perhaps I made grammatical mistake with the multiple of axis. But my question stays. Can I somehow redefine those darn things. I had to make some changes to my program and it all went down the drain. Please don't tell me the only way is to use quaternions and the like.

McDonte

20-12-2011 02:23:10

Actually I do not know but I really doubt there is a way to redefine these axis. Even if there is one this would be really bad coding style since the whole model of your three dimensional world would not be unique anymore... I am sure there is a better solution, probably using quaternions, sorry

Pyritie

20-12-2011 02:38:21

So the title says it all. Perhaps I made grammatical mistake with the multiple of axis. But my question stays. Can I somehow redefine those darn things. I had to make some changes to my program and it all went down the drain. Please don't tell me the only way is to use quaternions and the like.

A single node or every node?

If it's just a single node, a crude workaround is to just add another node to the scene graph so it kinda "comes between" your old parent and old child. Then rotate that node's axis to be correct.

But if it's every node then as far as I'm aware you can't change it.

You might want to try asking on the regular ogre forums though, since they're a lot more active than here.

Tubulii

01-01-2012 20:08:03

If it's just a single node, a crude workaround is to just add another node to the scene graph so it kinda "comes between" your old parent and old child. Then rotate that node's axis to be correct.

I think that is the "How to create a camera system". It is explained in the Ogre Wiki.

But you could set the Orientation back to ZERO (mynode.Orientation = Orientation.Zero) [sorry, quaternions

]. That should reset any rotation. If you want to rotate your camera, I higly recommend to read the wiki and look at the CameraMan(ager) class in the Mogre sample project.

Beauty

15-01-2012 16:44:28

Yes, the camera tutorial explains a good suggestion by usage of "helper nodes". Then you can manage your nodes by Euler Angles very well.

Here is the link:

http://www.ogre3d.org/tikiwiki/3rd+pers ... m+tutorial

But keep in mind that Euler Angles can cause problems in relation to the

**Gimbal Lock**.

Further information and a video tutorial you find here:

http://www.ogre3d.org/tikiwiki/-Gimbal+Lock
For my application I also need an other coordinate system.

My solution: I wrote a converter class which converts coordinates from my custom coordinate system to the Ogre coordinate system (in Euler angles).

As second step I converted the Ogre related Euler Angles to Ogre quaternions.

Well, this would not work for all kinds of applications, but for my needs it's fine.

More difficult is to convert Ogre quaternions back to Euler Angles. In general it works, but the angles can be different than you expect. (Because one quaternion state can be created by different combinations of Euler Angles. When you read out the Euler Angles from Quaternions, you will get ONE combination. But this could be different to your "wanted" combination.)

Also important:

When you read Euler Angles from quaternions, you will get different value combination by Mogre in comparison to Ogre (C++). Also there is a bug (Mogre only) that in special cases a returned value is null.

The reason is, that Mogre currently uses System.Math instead of Mogre.Math for math functions like Sin().

All needed knowledge I found out and reported it long time ago. Unfortunately this bug wasn't fixed until today.

As long as you know about this and add a null check, you don't need to care about.

Details I added to the Mogre bugtracker (including links to further details/solutions).

- Mogre.Math.Sin() has problems [/*:m]

- Quaternion.Yaw returns NaN (not defined) in 2 special cases [/*:m]

- wrap/improve Quaternion.GetYaw() -- support parameter[/*:m][/list:u]

Beauty

16-01-2012 01:06:31

**@ eddy**
Is there a way to redefine a nodes roll and pitch axis?

So the title says it all. Perhaps I made grammatical mistake with the multiple of axis. But my question stays. Can I somehow redefine those darn things. I had to make some changes to my program and it all went down the drain. Please don't tell me the only way is to use quaternions and the like.

Perhaps the

**Euler Angle Class** of user Kojack is useful for you:

http://www.ogre3d.org/tikiwiki/Euler+Angle+Class
The Euler class allows you to directly set/get absolute pitch, yaw or roll values without affecting each other, for example setting the orientation to face east while preserving the pitch and roll.

**update**
I looked to the source code of the class now.

It should work even with the unfixed Mogre bug, because the related functions (getYaw() etc.) are not used by the class.

You just need to port the code to C#. (In this case, please publish the result.)

But before you should search in the forums. Maybe somebody still created a C# clone.

Beauty

17-01-2012 12:48:51

Beauty

17-01-2012 12:59:39

**@ eddie**
Here I quote 2 posts of the splitted topic, which could be useful for your problem. (If you don't want to follow the whole splitted discussion.)

Maybe somebody still created a C# clone.

Ahm, *looking for it*... there it is:

(the old version, i will it update in the next days)

*(VB.Net)*

`Imports Mogre`

Public Class Euler

' ConstrucTor which takes yaw, pitch and roll values.

Public Sub New()

MyClass.New(New Radian(0.0F), New Radian(0.0F), New Radian(0.0F))

End Sub

Public Sub New(ByVal yaw As Radian)

MyClass.New(yaw, New Radian(0.0F), New Radian(0.0F))

End Sub

Public Sub New(ByVal yaw As Radian, ByVal pitch As Radian)

MyClass.New(yaw, pitch, New Radian(0.0F))

End Sub

Public Sub New(ByVal Oriantation As Quaternion)

MyClass.New(Oriantation.Yaw, Oriantation.Pitch, Oriantation.Roll)

End Sub

Public Sub New(ByVal Euler As Euler)

MyClass.New(Euler.m_yaw, Euler.m_pitch, Euler.m_roll)

End Sub

Public Sub New(ByVal yaw As Radian, ByVal pitch As Radian, ByVal roll As Radian)

m_yaw = yaw

m_pitch = pitch

m_roll = roll

m_changed = True

End Sub

''' <summary>

''' Get the Yaw angle.

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetYaw() As Radian

Return m_yaw

End Function

''' <summary>

''' Get the Pitch angle.

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetPitch() As Radian

Return m_pitch

End Function

''' <summary>

''' Get the Roll angle.

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetRoll() As Radian

Return m_roll

End Function

''' <summary>

''' Apply a relative yaw. (Adds angle To current yaw)

''' Angles wrap around within the range 0 To 2*PI radians (0 To 360 degrees)

''' </summary>

''' <param name="y"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function yaw(ByVal y As Radian) As Euler

m_yaw += y

If m_yaw.ValueRadians() < 0.0F Then

m_yaw = System.Math.IEEERemainder(m_yaw.ValueRadians(), Math.PI * 2.0F) + Math.PI * 2.0F

ElseIf m_yaw.ValueRadians() > Math.PI Then

m_yaw = System.Math.IEEERemainder(m_yaw.ValueRadians(), Math.PI * 2.0F)

End If

m_changed = True

Return Me

End Function

''' <summary>

''' Apply a relative pitch. (Adds angle To current pitch)

''' </summary>

''' <param name="p"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function pitch(ByVal p As Radian) As Euler

m_pitch += p

m_changed = True

Return Me

End Function

''' <summary>

''' Apply a relative roll. (Adds angle To current roll)

''' </summary>

''' <param name="r"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function roll(ByVal r As Radian) As Euler

m_roll += r

m_changed = True

Return Me

End Function

''' <summary>

''' Set the yaw.

''' </summary>

''' <param name="y"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function SetYaw(ByVal y As Radian) As Euler

m_yaw = y

m_changed = True

Return Me

End Function

''' <summary>

''' Set the pitch.

''' </summary>

''' <param name="p"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function SetPitch(ByVal p As Radian) As Euler

m_pitch = p

m_changed = True

Return Me

End Function

''' <summary>

''' Set the roll.

''' </summary>

''' <param name="r"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function SetRoll(ByVal r As Radian) As Euler

m_roll = r

m_changed = True

Return Me

End Function

''' <summary>

''' Get a vector pointing forwards.

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetForward() As Vector3

Return ToQuaternion() * Vector3.NEGATIVE_UNIT_Z

End Function

''' <summary>

''' Get a vector pointing To the right.

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetRight() As Vector3

Return ToQuaternion() * Vector3.UNIT_X

End Function

''' <summary>

''' Get a vector pointing up.

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetUp() As Vector3

Return ToQuaternion() * Vector3.UNIT_Y

End Function

''' <summary>

''' Calculate the quaternion of a euler object.

''' The result is cached, it is only recalculated when the component euler angles are changed.

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function ToQuaternion() As Quaternion

If m_changed Then

m_cachedQuaternion = New Quaternion(m_yaw, Vector3.NEGATIVE_UNIT_Y) * New Quaternion(m_pitch, Vector3.UNIT_X) * New Quaternion(m_roll, Vector3.NEGATIVE_UNIT_Z)

m_changed = False

End If

Return m_cachedQuaternion

End Function

'Public Shared OperaTor Quaternion(ByVal ImpliedObject As Euler)

' Return ToQuaternion()

' End OperaTor

''' <summary>

''' Casting operaTor. This allows any ogre function that wants a Quaternion To accept a Euler instead

''' </summary>

''' <param name="ImpliedObject"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Shared Widening Operator CType(ByVal ImpliedObject As Euler) As Quaternion

Return ImpliedObject.ToQuaternion

End Operator

''' <summary>

''' Set the yaw and pitch To face in the given direction.

''' The direction doesn't need To be normalised.

''' Roll is unaffected.

''' </summary>

''' <param name="v"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function SetDirection(ByVal v As Vector3) As Euler

Dim d As Vector3 = v.NormalisedCopy

m_pitch = Math.ASin(d.y)

m_yaw = Math.ATan2(d.z, d.x) + New Radian((Math.PI / 2.0))

m_changed = True

Return Me

End Function

''' <summary>

''' Get the angular difference between the current yaw and the specified yaw.

''' Only yaw is considered, pitch and roll are ignored.

''' </summary>

''' <param name="a"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetYawToDirection(ByVal a As Radian) As Radian

Dim angle As Single = (a - m_yaw).ValueRadians()

If angle > Math.PI Then

angle = -Math.PI * 2.0F + angle

ElseIf angle < -Math.PI Then

angle = Math.PI * 2.0F + angle

End If

Return New Radian(angle)

End Function

''' <summary>

''' Get the angular difference between the current yaw and the specified direction vector.

''' Only yaw is considered, pitch and roll are ignored.

''' </summary>

''' <param name="v"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetYawToDirection(ByVal v As Vector3) As Radian

Return GetYawToDirection(New Radian(Math.ATan2(v.z, v.x) + New Radian(Math.PI / 2.0F)))

End Function

''' <summary>

''' Get the angular difference between the current yaw and the specified euler object.

''' Only yaw is considered, pitch and roll are ignored.

''' </summary>

''' <param name="e"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function GetYawToDirection(ByVal e As Euler) As Radian

Return GetYawToDirection(e.m_yaw)

End Function

''' <summary>

''' Change the yaw To face in the direction of the vector.

''' Only yaw is changed, pitch and roll are ignored.

''' </summary>

''' <param name="v"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function yawToDirection(ByVal v As Vector3) As Euler

m_yaw = GetYawToDirection(v)

m_changed = True

Return Me

End Function

''' <summary>

''' Change the yaw To face in the direction of the euler object.

''' Only yaw is changed, pitch and roll are ignored.

''' </summary>

''' <param name="e"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Function yawToDirection(ByVal e As Euler) As Euler

'C++ TO VB CONVERTER WARNING: The following line was determined To be a copy construcTor call - this should be verified and a copy construcTor should be created if it does not yet exist:

'ORIGINAL LINE: m_yaw = GetYawToDirection(e);

m_yaw = GetYawToDirection(New Euler(e))

m_changed = True

Return Me

End Function

Public Function ToDisplayString() As String

Return String.Format("X: {0:00}° Y: {1:00}° Z: {2:00}°", GetPitch.ValueDegrees, GetYaw.ValueDegrees, GetRoll.ValueDegrees)

End Function

Public Shared Function ParseDisplayString(ByVal str As String) As Euler

Dim data = str.Split(" ")

If data.Length = 6 Then

Dim roll = Single.Parse(data(5))

Dim pitch = Single.Parse(data(1))

Dim yaw = Single.Parse(data(3))

Return New Euler(New Degree(yaw), New Degree(pitch), New Degree(roll))

Else

Return Nothing

End If

End Function

'' stream operaTor, for printing the euler component angles To a stream

' Public Shared OperaTor <<(ByVal o As IO.Stream, ByVal e As Euler) As IO.Stream

' o << "<Y:" << e.m_yaw << ", P:" << e.m_pitch << ", R:" << e.m_roll << ">"

' Return o

' End OperaTor

Protected m_yaw As Radian = New Radian ' Rotation around the Y axis.

Protected m_pitch As Radian = New Radian ' Rotation around the X axis.

Protected m_roll As Radian = New Radian ' Rotation around the Z axis.

Protected m_cachedQuaternion As Quaternion = New Quaternion() ' Cached quaternion equivalent of this euler object.

Protected m_changed As Boolean ' Is the cached quaternion out of date?

End Class

What do you think about?

You are correct, but I am not a Mogre Developer... but it is possible.

I looked to the source code of the class now.

**It should work even with the unfixed Mogre bug**, because the related functions (getYaw() etc.) are not used by the class.

Important:

**This is only related to the OLD class.**

By my motivation Kojack published his new improved class in the wiki today.

BUT: It seems so that his new class uses the methods/properties, which returns "buggy" values.

So I suppose **we can't use the NEW class for Mogre as long as the Orientation bug is not fixed**.

The link to the old Euler Angle Class you grabb from the history of the wiki page:

http://www.ogre3d.org/tikiwiki/tiki-pag ... &preview=4

Ahm, *looking for it*... there it is

Nice.

I think it should be easy create C# code from it by usage of a VB-C# converter.

For example this one:

http://www.developerfusion.com/tools/co ... harp-to-vb