Thread: [Algorithms] Quaternion pre/post-multiply and pitching problems
Brought to you by:
vexxed72
From: Chris H. <c.h...@ke...> - 2001-08-29 17:24:01
|
Hi, I have this weird problem. I tried to implement a first-person-shooter camera using quaternions today and implemented two methods in my camera class: - AddPitch(angle_in_degrees) - AddYaw(angle_in_degrees) When my mouse moves in the Y direction, AddPitch is called with the appropriate movement delta and AddYaw is called in case of X movement. These methods do the following (in pseudo-code): AddPitch/Yaw: - relative_rotation_quat = rotation quaternion with the amount of pitch or yaw specified - rotation_quat = rotation_quat * relative_rotation_quat This approach gives me faulty results when moving the camera at the start pitch=0 and yaw=90 (camera is parallel to X-axis). When I move my mouse in the Y direction, pitch is changed but the camera does a roll instead of a pitch change. When I change the pitch method to do the following: AddPitch: - relative_rotation_quat = rotation quaternion with the amount of pitch or yaw specified - rotation_quat = relative_rotation_quat * rotation_quat And leave the AddYaw as is, then the whole thing works fine....... Now could anybody tell me what is going wrong?? Chris --- Keep IT Simple Software Van Alphenstraat 12 7514 DD Enschede W: http://www.keepitsimple.nl E: mailto:in...@ke... T: +31 53 4356687 |
From: Jon W. <hp...@mi...> - 2001-08-30 07:19:35
|
> And leave the AddYaw as is, then the whole thing works > fine....... Now could > anybody tell > me what is going wrong?? It might be that you're doing your math in absolute coordinates. What's "pitch" when you're facing negative Z (rotation around the X axis) becomes "roll" when you're facing positive X. Unless you're planning on supporting falling down or other camera animation in your FPS, it'd probably be easier for you to store your orientation simply as heading and pitch out from the worldspace point. Then get the correct quaternion or rotation matrix out of that data each frame. If you need a full quaternion, you must make sure to apply your delta quaternions in oriented-point-relative coordinates, not absolute coordinates. Cheers, / h+ |
From: Chris H. <c.h...@ke...> - 2001-08-30 16:14:08
|
> > And leave the AddYaw as is, then the whole thing works > > fine....... Now could > > anybody tell > > me what is going wrong?? > > It might be that you're doing your math in absolute coordinates. What's > "pitch" when you're facing negative Z (rotation around the X axis) becomes > "roll" when you're facing positive X. > > Unless you're planning on supporting falling down or other camera > animation > in your FPS, it'd probably be easier for you to store your orientation > simply as heading and pitch out from the worldspace point. Then get the > correct quaternion or rotation matrix out of that data each frame. > > If you need a full quaternion, you must make sure to apply your delta > quaternions in oriented-point-relative coordinates, not absolute > coordinates. I think i'm using relative coordinates. I use this scheme: - calculate delta x-movement - calculate delta y-movement pitch_quat.calculatepitch(delta_y) yaw_quat.calculateyaw(delta_x) totalrotation_quat = pitch_quat*yaw_quat*totalrotation_quat Chris |
From: Jon W. <hp...@mi...> - 2001-08-30 17:33:13
|
> I think i'm using relative coordinates. I use this scheme: > > - calculate delta x-movement > - calculate delta y-movement > > pitch_quat.calculatepitch(delta_y) > yaw_quat.calculateyaw(delta_x) > totalrotation_quat = pitch_quat*yaw_quat*totalrotation_quat This can't work, because calculatepitch() and calculateyaw() need to be done _in the target's coordinate space_ (i e assuming the target is pointing straight ahead). If you do calculations using a single quat, they're done in absolute coordinates. Cheers, / h+ |
From: Chris H. <c.h...@ke...> - 2001-08-30 19:35:51
|
> > I think i'm using relative coordinates. I use this scheme: > > > > - calculate delta x-movement > > - calculate delta y-movement > > > > pitch_quat.calculatepitch(delta_y) > > yaw_quat.calculateyaw(delta_x) > > totalrotation_quat = pitch_quat*yaw_quat*totalrotation_quat > > This can't work, because calculatepitch() and calculateyaw() need > to be done > _in the target's coordinate space_ (i e assuming the target is pointing > straight ahead). If you do calculations using a single quat, > they're done in > absolute coordinates. You wouldn't by any chance have some pseudo code of this lying around would you :-) ? Chris --- Keep IT Simple Software Van Alphenstraat 12 7514 DD Enschede W: http://www.keepitsimple.nl E: mailto:in...@ke... T: +31 53 4356687 |
From: mark_me <ma...@so...> - 2001-08-31 14:11:43
|
You don't need any code for that , as Jon said , you only need to keep your angles ( whatever you want to call them , although using Pitch and Yaw here are wrong IMHO ) and rebuild your Quat every frame. If you have a target and want to track it by your camera , you need to do the following : - Get target vector relative to the camera position by subtracting the target position from the camera position. - calculate the length of the projection of this vector on the XY plane length_xy = Sqrt( x*x + y*y ) - your angels now are : heading = acos( x/ length_xy ); // you need to fix the sign of the angle by checking the quarter you are in the other angle :) = atan2( z / length_xy ); Note that since you are using quaternions then it could be faster to build the quaternion directly by getting the sin and cos of the angles divided by 2 instead of doing the inverse function which I think are very expensive on all platforms , you need some trigonometric relations to get what you want. Why can't you multiply by a delta ? The mathematical explanation would be : step 1 : totalrotation_quat = Identity ; // the begining step 2 : totalrotation_quat = yaw_quat1 * pitch_quat1 * totalrotation_quat; // first delta step 3 : totalrotation_quat = yaw_quat2 * pitch_quat2 * totalrotation_quat; // second delta Now after these 3 steps your totalrotation_quat will be equivalent to : totalrotation_quat = yaw_quat2 * pitch_quat2 * yaw_quat1 * pitch_quat1 But what you actually want is totalrotation_quat = yaw_quat2 * yaw_quat1 * pitch_quat2 * pitch_quat1 ; and obviously the two are not equivalent due to the fact that quaternions are not commutative. if you have to keep the orientation quat , and do your calculations of pitch and yaw in camera space, then you will have problems aligning the camera with world space xy plane , i.e. you might end up with a camera orientation that looks at the target directly but upside-down , which I don't think you want. I can send you some code for camera target tracking , if the above is not clear enough ( sorry I know that my English is not the best ;) Mark -----Original Message----- From: gda...@li... [mailto:gda...@li...]On Behalf Of Chris Haarmeijer Sent: August 30, 2001 12:40 PM To: gda...@li... Subject: RE: [Algorithms] Quaternion pre/post-multiply and pitching problems > > I think i'm using relative coordinates. I use this scheme: > > > > - calculate delta x-movement > > - calculate delta y-movement > > > > pitch_quat.calculatepitch(delta_y) > > yaw_quat.calculateyaw(delta_x) > > totalrotation_quat = pitch_quat*yaw_quat*totalrotation_quat > > This can't work, because calculatepitch() and calculateyaw() need > to be done > _in the target's coordinate space_ (i e assuming the target is pointing > straight ahead). If you do calculations using a single quat, > they're done in > absolute coordinates. You wouldn't by any chance have some pseudo code of this lying around would you :-) ? Chris --- Keep IT Simple Software Van Alphenstraat 12 7514 DD Enschede W: http://www.keepitsimple.nl E: mailto:in...@ke... T: +31 53 4356687 _______________________________________________ GDAlgorithms-list mailing list GDA...@li... http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list |
From: Chris H. <c.h...@ke...> - 2001-08-30 16:18:32
|
> > Unless you're planning on supporting falling down or other camera > > animation > > in your FPS, it'd probably be easier for you to store your orientation > > simply as heading and pitch out from the worldspace point. Then get the > > correct quaternion or rotation matrix out of that data each frame. > > > > If you need a full quaternion, you must make sure to apply your delta > > quaternions in oriented-point-relative coordinates, not absolute > > coordinates. > > I think i'm using relative coordinates. I use this scheme: > > - calculate delta x-movement > - calculate delta y-movement > > pitch_quat.calculatepitch(delta_y) > yaw_quat.calculateyaw(delta_x) > totalrotation_quat = pitch_quat*yaw_quat*totalrotation_quat Whoops, I meant: totalrotation_quat = totalrotation_quat*pitch_quat*yaw*quat Sorry, Chris |
From: mark_me <ma...@so...> - 2001-08-30 07:30:53
|
Just to make sure that I understood you, what do mean exactly by pitch and yaw? Usually pitch and yaw are used for airplanes to describe the incremental changes relative to the instantaneous airplane orientation. for example if the Airplane starts at Identity orientation , rolled by 90deg , then pitched by 90deg , this pitching will change the heading of the airplane while its x-axis will still be parallel to the XY plane ( considering that the ground is on XY plane and Z points to the sky ). What you usually want to do for camera navigation is changing the heading the actual angle around the world space Z-Axis ) and the Banking ( or maybe elevation ? I'm not sure about the naming ) which is the angle between the x axis of the camera and the projection of this axis over the world space XY plane. To do this you should rebuild the orientation quaternion every frame , otherwise the dependency of the order of your quaternion multiplication will screw up your results. You need to do something like : Quaternion heading( cam_heading_radians , Z_AXIS ); Quaternion banking( cam_banking_radians , Y_AXIS ); Quaternion camera_orientation = heading * banking ; Hope this is helpful :) Mark -----Original Message----- From: gda...@li... [mailto:gda...@li...]On Behalf Of Chris Haarmeijer Sent: August 29, 2001 10:28 AM To: Algorithms Subject: [Algorithms] Quaternion pre/post-multiply and pitching problems Hi, I have this weird problem. I tried to implement a first-person-shooter camera using quaternions today and implemented two methods in my camera class: - AddPitch(angle_in_degrees) - AddYaw(angle_in_degrees) When my mouse moves in the Y direction, AddPitch is called with the appropriate movement delta and AddYaw is called in case of X movement. These methods do the following (in pseudo-code): AddPitch/Yaw: - relative_rotation_quat = rotation quaternion with the amount of pitch or yaw specified - rotation_quat = rotation_quat * relative_rotation_quat This approach gives me faulty results when moving the camera at the start pitch=0 and yaw=90 (camera is parallel to X-axis). When I move my mouse in the Y direction, pitch is changed but the camera does a roll instead of a pitch change. When I change the pitch method to do the following: AddPitch: - relative_rotation_quat = rotation quaternion with the amount of pitch or yaw specified - rotation_quat = relative_rotation_quat * rotation_quat And leave the AddYaw as is, then the whole thing works fine....... Now could anybody tell me what is going wrong?? Chris --- Keep IT Simple Software Van Alphenstraat 12 7514 DD Enschede W: http://www.keepitsimple.nl E: mailto:in...@ke... T: +31 53 4356687 _______________________________________________ GDAlgorithms-list mailing list GDA...@li... http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list |