Rotate Object with Yaw Pitch Roll Hint

Everything related to 3D programming
Henry00
User
User
Posts: 88
Joined: Thu Jul 12, 2012 7:00 pm
Location: Germany
Contact:

Rotate Object with Yaw Pitch Roll Hint

Post by Henry00 »

In case you get a little confused or have strange rotations that don't make much sense when rotating any object (node, camera, entity, entity bone) as you may be expecting to use yaw pitch roll, this is how you can do that:

Code: Select all

; X = Yaw, Y = Pitch, Z = Roll
RotateEntityBone(#Entity, Bone$, 0, 0, 0, #PB_Absolute)
RotateEntityBone(#Entity, Bone$, 0, X, 0, #PB_Relative)
RotateEntityBone(#Entity, Bone$, 0, 0, Y, #PB_Relative)
RotateEntityBone(#Entity, Bone$, Z, 0, 0, #PB_Relative)
User avatar
Comtois
Addict
Addict
Posts: 1432
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Comtois »

by default rotation are local. you can select the type of rotation with the following constants :

Code: Select all

      RotateEntity(1, 1, 0, 0, #PB_Relative | #PB_Local)
      RotateEntity(1, 1, 0, 0, #PB_Relative | #PB_Parent) 
      RotateEntity(2, 1, 0, 0, #PB_Relative | #PB_World)
This is the same principle for command MoveXXX()
Please correct my english
http://purebasic.developpez.com/
Henry00
User
User
Posts: 88
Joined: Thu Jul 12, 2012 7:00 pm
Location: Germany
Contact:

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Henry00 »

Hm I don't quite understand what is happening here though:

Code: Select all

MoveCamera(0, 3, 5, 7, #PB_Absolute | #PB_World)
Debug CameraX(0) ; 3.0
Debug CameraY(0) ; 45.0
Debug CameraZ(0) ; 157.0
This not just happens with #PB_World but the same values with #PB_Local and #PB_Parent, only if I don't use a flag like #PB_World this will be 3, 5 and 7.
I can only confirm that X returns the correct value...

Attempting to use this logic to move the camera results in about 50 calls to get a complete float overflow -1.#IND

Code: Select all

MoveCamera(0, CameraX(0) + 5, CameraY(0), CameraZ(0), #PB_Absolute) ; (this works, without a |#PB_World)

Code: Select all

RotateCamera(0, 132, 50, 10, #PB_Absolute) ; with or without additional flag makes no difference
Debug CameraPitch(0, #False) ; 125.47937774658203
Debug CameraYaw(0, #False) ; 42.17967224121094
Debug CameraRoll(0, #False) ; -9.02103519439697
I can understand small float errors, but this is way way off, when it is set to #True as well:

137.51800537109375
-130.00001525878906
-9.02103900909424

It's starting to be no wonder that I cannot use #PB_Absolute for precise movements.

What is #PB_Relative doing? If these functions fail to return correct values, this is quite confusing and the help file gives no information at all..

Thanks for the quick support all the time!
User avatar
Comtois
Addict
Addict
Posts: 1432
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Comtois »

You are right, there is something wrong. MoveCamera() can be one of these :
MoveCamera(0, 3, 5, 7, #PB_Absolute) ; it is necessarily in the world
MoveCamera(0, 3, 5, 7, #PB_Relative) ; along world axes
MoveCamera(0, 3, 5, 7, #PB_Local) ;along it's own axes (relative to orientation).

you cant combine constants.
Please correct my english
http://purebasic.developpez.com/
Henry00
User
User
Posts: 88
Joined: Thu Jul 12, 2012 7:00 pm
Location: Germany
Contact:

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Henry00 »

The help file would have to be updated to reflect those facts as it does claim that it's possible.
The move mode. It can be one of the following values:
#PB_Relative: relative move, from the current camera position (default).
#PB_Absolute: absolute move to the specified position.

combined with one of the following values:
#PB_Local : local move.
#PB_Parent: move relative to the parent position.
#PB_World : move relative to the world.
Confirmed that movement works without combinations, but the rotation is a PureBasic problem...?
User avatar
Comtois
Addict
Addict
Posts: 1432
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Comtois »

Henry00 wrote: but the rotation is a PureBasic problem...?
we will check rotation, there is probably something wrong
Please correct my english
http://purebasic.developpez.com/
User avatar
Comtois
Addict
Addict
Posts: 1432
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Comtois »

http://www.ogre3d.org/forums/viewtopic. ... 5&start=11

The problem is that there are multiple combinations of pitch/yaw/roll which result in the same quaternion.
When you try to convert a quaternion to euler, the algorithm has no way of knowing which combination of values you wanted from the many valid possibilities.

For example, think of a spaceship facing forwards. Now pitch the ship 180 degrees. It is now upside down facing backwards.
Now think of a second spaceship facing forwards. Don't pitch it, instead yaw it 180 degrees and roll it 90 degrees. It's now upside down facing backwards.
Two different combinations of euler angles, with the same end result. Both would generate the quaternion <0,1,0,0> (off the top of my very tired head).
The quaternion doesn't care how the spaceship got to being upside down and backwards, it just knows that's how it's facing, and that's all it stores.
When converting back to euler from the quaternion, which result should it tell you: P=180,Y=0,R=0 or P=0,Y=180,R=90?

The moral of the story is: going from a quaternion to a euler combination will always give a correct result, but maybe not the one you wanted. If you want consistant eulers, you need to store them as eulers.
Please correct my english
http://purebasic.developpez.com/
Henry00
User
User
Posts: 88
Joined: Thu Jul 12, 2012 7:00 pm
Location: Germany
Contact:

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Henry00 »

I see, you are perfectly right. I will try to learn how Quaternions work although they seem much more complex (I grew up with eulers).
Sorry to cause you trouble but at least these questions got answered in case someone else happens to get stuck here too.

It does make me wonder how I am "supposed" to rotate the camera, I can only assume that's the whole reason #PB_Relative was build, so no-one has to bother with Quaternions.
There was a small oversight though, using those FetchOrientation and SetOrientation procedures you won't be able to rotate entity bones.

[update]
Wait the thing that confused me the most is that we have yaw pitch roll getter procedures, in some cases there is "Direction" and the manual states "Rotates the #Camera according to the specified x,y,z angle values", it's all a little confusing...
User avatar
Comtois
Addict
Addict
Posts: 1432
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Comtois »

extract from this tutorial
Q. Why do the tutorials and people on the forum suggest using two scene nodes to attach my camera to?

A. The recommendation is to create a scene node, say "CamNode" and a pitch node, say "PitchNode". "PitchNode" is attached to "CamNode" and the camera is attached to "PitchNode". Movement and Yaw are applied to the CamNode. Pitch is applied to the "PitchNode", only. The reason for this is because one can generate roll through euler angles of pitch and yaw. Often one uses the mouse to control the camera look angle. One expects to move the mouse up to look up, right to look right, down to look down. However this is the same as pitch up, yaw right and pitch down. Try this with a desk object. That sequence induces roll. Using two separate nodes gives you the equivalent of a flat disk that floats around. Attached to the bottom of that disk is a camera that can look only up or down. By rotating the disk and moving the camera up or down you can view any angle. Yaw on the disk affects the camera, but pitch on the camera does not affect the disk. This provides the effect that most people expect.

Alternate A. For a simple Free Camera you can use the one node and just rotate in the appropriate coordinate space. Once you want to start mixing "roll" into this, you should go back to completely local space rotations---at which point you're probably not trying to make a simple Free Camera for debug purposes.

Code: Select all

node->pitch( mPitch, Node::TS_LOCAL );
 node->yaw( mYaw, Node::TS_WORLD );
 node->translate( mTranslate, Node::TS_LOCAL );

The effect of this is to pitch the scenenode relative to itself, but to yaw the scenenode relative to the world. This means yaw is always horizontal and no roll is induced by the two rotations. The translate call ensures you are always moving along the SceneNode's z axis. i.e., the direction it is facing.
Please correct my english
http://purebasic.developpez.com/
Olby
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Jan 12, 2009 10:33 am
Contact:

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Olby »

I can't get my head around this as well. I come from the world of DarkBASIC Pro, which had a simple Euler mechanism (X/Y/Z) and all beginners were able to understand it in minutes. Hence in DBPro it took me about 15 minutes the first time I tried to create a proper mouse look. In PB+OGRE I still can't get it just right. My camera spins out of control and does all sorts of other unexpected behaviour. Rotation method should be revised or at least supply us with a good documentation on this.
Intel Core i7 Quad 2.3 Ghz, 8GB RAM, GeForce GT 630M 2GB, Windows 10 (x64)
User avatar
Comtois
Addict
Addict
Posts: 1432
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Comtois »

Olby wrote: In PB+OGRE I still can't get it just right. My camera spins out of control and does all sorts of other unexpected behaviour. Rotation method should be revised or at least supply us with a good documentation on this.
Have you a snippet ?
Please correct my english
http://purebasic.developpez.com/
Henry00
User
User
Posts: 88
Joined: Thu Jul 12, 2012 7:00 pm
Location: Germany
Contact:

Re: Rotate Object with Yaw Pitch Roll Hint

Post by Henry00 »

I know exactly what you mean (the camera can even move by itself!!), I confirmed the method given above by amazing Comtois:

Code: Select all

    ; create a node that will handle camera
    CreateNode(0)
    
    ; create a node that will handle pitch
    CreateNode(1)
    
    AttachNodeObject(0, NodeID(1)) ; attach pitchnode to the cameranode
    AttachNodeObject(1, CameraID(0)) ; attach camera to the pitchnode
    
    MouseX = 0
    MouseY = 0
    
    Repeat
      Screen3DEvents()

      If ExamineMouse()
        MouseX - MouseDeltaX() * #CameraSpeed * 0.05
        MouseY - MouseDeltaY() * #CameraSpeed * 0.05
      EndIf

      ; this will cause any value to wrap around.
      While MouseX >  180 : MouseX - 360 : Wend
      While MouseX < -180 : MouseX + 360 : Wend
      While MouseY >  180 : MouseY - 360 : Wend
      While MouseY < -180 : MouseY + 360 : Wend
      
      RotateNode(0, 0, MouseX, 0, #PB_Local) ; yaw: camera node
      RotateNode(1, MouseY, 0, 0, #PB_Local) ; pitch: pitch node
      MoveNode(0, KeyX, 0, KeyY, #PB_Local)
      
      Debug StrF(MouseX) + " = " + StrF(NodeYaw(0))
      Debug StrF(MouseY) + " = " + StrF(NodePitch(1))
This finally gives results I can work with, just don't exceed -180/+180 and you will get 100% accurate yaw/pitch/roll that does not break your custom rotations!
[update] made a simple wrapper that ensures the above is always true.

A big thanks Comtois, it's a little workaround but a great technique!
Are you sure however, you wish everyone to build this workaround? Perhaps a flag for "stable yaw pitch roll", I am just mumbling here but this gets too confusing for beginners..

Code: Select all

local y, p, r = game.camera:rotation()
game.camera:rotation(y + -glue.input.mouseDX() * 0.25, p + -glue.input.mouseDY() * 0.25, r)
(this is in lua) however that should also be what PureBasic is supposed to do, logical math.

[update]
If you use this method please don't use CameraYaw/CameraPitch/CameraRoll as they will return garbage, only get them from NodeYaw and NodePitch.
Post Reply