Page 1 of 1
Rotate Object with Yaw Pitch Roll Hint
Posted: Sat Jul 20, 2013 3:53 pm
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)
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 5:46 pm
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()
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 7:48 pm
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!
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 8:18 pm
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.
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 8:32 pm
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...?
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 8:57 pm
by Comtois
Henry00 wrote: but the rotation is a PureBasic problem...?
we will check rotation, there is probably something wrong
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 10:09 pm
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.
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 10:38 pm
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...
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Sun Jul 21, 2013 11:06 pm
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.
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Mon Jul 22, 2013 10:44 am
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.
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Mon Jul 22, 2013 11:02 am
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 ?
Re: Rotate Object with Yaw Pitch Roll Hint
Posted: Mon Jul 22, 2013 11:07 am
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.