I think I ran into a similar problem building the orientation state using AxisAngles. I believe you have to first build the "default" state before you can multiply the (yaw/pitch/roll) quaternions.
On Sun, Mar 4, 2012 at 12:31 AM, Craig Louie <craiglo...@gmail.com> wrote: > I've tried both Joel and Tony's methods, but I'm still unsure of how I can > escape the inherent aliasing problem of Euler Angles. > > With Joel's method, for instance, after I have used Slerp to get a > rotation quaternion, I still need to convert the resulting quaternion back > into Euler Angles (with QuaternionAngles()) because the Source engine > ultimately needs orientation in QAngle form when I call > engine->SetViewAngles(viewangles). Any thoughts on this? > > Also, I've learned more about the nature of the twisting hitch experienced > when looking straight up/down (this was my original problem). When I turn > off motion blur, the hitch isn't visible. My theory is that the twisting > hitch I am seeing is a result of the player's orientation twisting at the > instant the player looks straight up/down. > > Below is a part of a log showing the changes in viewangle as I pitch down > through pitch=90 (as shown in my youtube video). > > 88.025864 0.000000 0.000000 > 88.136208 0.000000 0.000000 > 88.278770 0.000000 0.000000 > 88.421890 0.000000 0.000000 > 88.531670 0.000000 0.000000 > 88.683762 0.000000 0.000000 > 88.784576 0.000000 0.000000 > 88.976646 0.000000 0.000000 > 89.037476 0.000000 0.000000 > 89.261894 0.000000 0.000000 > 89.290375 0.000000 0.000000 > 89.522987 0.000000 0.000000 > 89.543274 0.000000 0.000000 > 89.787949 0.000000 0.000000 > 89.796173 0.000000 0.000000 > 89.950935 -0.000000 0.000000 > 89.989258 -0.000000 0.000000 > 89.796158 180.000000 180.000000 > 89.639793 -180.000000 -180.000000 > 89.543274 180.000000 180.000000 > 89.290382 -180.000000 -180.000000 > 89.266182 180.000000 180.000000 > 89.037491 -180.000000 -180.000000 > 88.784592 180.000000 180.000000 > 88.531693 -180.000000 -180.000000 > 88.334381 180.000000 180.000000 > 88.278809 -180.000000 -180.000000 > 88.025909 180.000000 180.000000 > > The sudden yaw and roll change to +/-180 is probably what is causing the > hitch. The motion blur is creating a blur effect as if the player is > spinning for an instant. How to get around this, I am not sure. > > > Here's my current code in in_joystick.cpp's JoyStickMove() function: > > //############################################################################### > > Vector vec_for, vec_rt, vec_up, vec_for_out, vec_rt_out, vec_up_out; > Quaternion viewangles_q, turn_q, look_q, roll_q, qTemp, qDelta, > qResult, viewangles_q_out; > > AngleVectors(viewangles, &vec_for, &vec_rt, &vec_up); > > //Converting the current viewangles to a Quaternion (viewangles_q). > RadianEuler viewangles_euler(viewangles); > AngleQuaternion(viewangles_euler, viewangles_q); > > //Build a set of quaternion transforms that rotate around > corresponding axes in local space by corresponding angles. > // NOTE: non-unit vectors will bias the resulting rotation angle (but > not the axis) > > VectorNormalize(vec_up); > AxisAngleQuaternion(vec_up, turn_angle, turn_q); > VectorNormalize(vec_rt); > AxisAngleQuaternion(vec_rt, look_angle, look_q); > VectorNormalize(vec_for); > AxisAngleQuaternion(vec_for, roll_angle, roll_q); > > //Combine Quaternions. > QuaternionMult(look_q, turn_q, qTemp); > QuaternionMult(qTemp, roll_q, qDelta); > > //Slerp > QuaternionSlerp(viewangles_q, qDelta, 1.0, qResult); > > //Applying the Quaternion rotation. > QuaternionMult(qResult, viewangles_q, viewangles_q_out); > > //Converting Quaternion into a QAngle for > engine->SetViewAngles(viewangles_out) > QAngle viewangles_out; > QuaternionAngles(viewangles_q_out, viewangles_out); > > COM_Log("viewangle_hitch.txt", "%2f %2f %2f \n", viewangles_out.x, > viewangles_out.y, viewangles_out.z); > > if (viewangles_out[PITCH] > 180) > { > viewangles_out[PITCH] -= 360; > } > else if (viewangles_out[PITCH] < -180) > { > viewangles_out[PITCH] += 360; > } > > if (viewangles_out[YAW] > 180) > { > viewangles_out[YAW] -= 360; > } > else if (viewangles_out[YAW] < -180) > { > viewangles_out[YAW] += 360; > } > > if (viewangles_out[ROLL] > 180) > { > viewangles_out[ROLL] -= 360; > } > else if (viewangles_out[ROLL] < -180) > { > viewangles_out[ROLL] += 360; > } > > //############################################################################### > > > Thanks! > > > > On Fri, Mar 2, 2012 at 12:40 AM, Craig Louie <craiglo...@gmail.com> wrote: > >> Thanks Tony and Joel for more awesome help. I didn't get as much time as >> I would have liked to work on it tonight. I will have to continue tomorrow >> night (and probably into the weekend). I'll keep the thread posted. Thanks! >> >> P.S. cool flight sim vid, Joel. Are you a fellow X-Wing/Tie Fighter fan? >> Freespace perhaps? >> >> >> >> On Thu, Mar 1, 2012 at 10:29 PM, Joel R. <joelru...@gmail.com> wrote: >> >>> http://www.youtube.com/watch?v=5y6a_oFtNiI >>> >>> >>> On Thu, Mar 1, 2012 at 10:35 PM, Tony "omega" Sergi <omegal...@gmail.com >>> > wrote: >>> >>>> This actually will work in Source, as the input/view stuff is basically >>>> identical: >>>> http://articles.thewavelength.net/269/ >>>> -Tony >>>> >>>> >>>> >>>> On Fri, Mar 2, 2012 at 5:09 AM, Craig Louie <craiglo...@gmail.com>wrote: >>>> >>>>> Thanks Joel! I'll also try out your method when I get home. I'll keep >>>>> everyone posted on my results. >>>>> >>>>> Thanks! >>>>> >>>>> >>>>> >>>>> On Thu, Mar 1, 2012 at 11:12 AM, Joel R. <joelru...@gmail.com> wrote: >>>>> >>>>>> Quaternion.h >>>>>> http://pastebin.com/hxTBab3T >>>>>> >>>>>> Quaternion.cpp >>>>>> http://pastebin.com/2WizAewD >>>>>> >>>>>> Quaternion Rotation Formulas (Yaw/Pitch/Roll) >>>>>> http://pastebin.com/BHRvcbCG >>>>>> >>>>>> I got most of the quaternion stuff from Ogre engine and converted to >>>>>> work on Source Engine. The functions you will be interested in using are >>>>>> FromRotationMatrix, ToRotationMatrix, AxisAngle, ToAxisAngle, >>>>>> GetRotationTo, ToAxes, Slerp, GetAngles, GetMatrix >>>>>> >>>>>> So basically you'll do what's below: (this is psuedocode, function >>>>>> names are not exact!) >>>>>> >>>>>> >>>>>> Quat current, target; >>>>>> current.FromRotationMatrix( ent->EntityWorldTransform() ); >>>>>> >>>>>> target = current; >>>>>> target = yaw( target, 10 ); //10 degrees to the right, this function >>>>>> is not part of Quat class for some reason >>>>>> >>>>>> current = Slerp( current, target, 0.2 ); //This is only 20%, you'll >>>>>> need to calculate the angle difference between current/target, and then >>>>>> move based on your angles per second speed. >>>>>> >>>>>> matrix3x4_t newRot; >>>>>> current.ToRotationMatrix( newRot ); >>>>>> ent->SetWorldTransform( newRot ); >>>>>> >>>>>> >>>>>> >>>>>> Enjoy! >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Thu, Mar 1, 2012 at 12:46 PM, Joel R. <joelru...@gmail.com> wrote: >>>>>> >>>>>>> The quaternion calculations you're doing are similar to just >>>>>>> manipulating the Euler Angles, which cause Gimbal Lock. >>>>>>> >>>>>>> The way I did it in my flight simulation is to create a Current >>>>>>> Quaternion (from the starting Matrix Transformation when user spawns) >>>>>>> and >>>>>>> Target Quaternion (where they want to rotate to). I also used some >>>>>>> formulas to rotate the quaternion in the individual yaw/pitch/roll >>>>>>> orientations, I recommend googling for these formulas. I then used the >>>>>>> Slerp formula to animate from the Current quaternion to the Target >>>>>>> quaternion. Slerp will avoid Gimbal-Lock entirely, which is very neat. >>>>>>> >>>>>>> After you do those calculations, just convert the new Current >>>>>>> Quaternion into a Matrix Transformation and set the Entity to take that >>>>>>> transform. >>>>>>> >>>>>>> I've used this to control the entity rotation as well as the camera, >>>>>>> it allows you to do some pretty nifty tricks. >>>>>>> >>>>>>> I'll look for the code, if I still have it, and I'll post it here >>>>>>> for you. Or if you figure out, please post a video =D >>>>>>> >>>>>>> Regards, >>>>>>> >>>>>>> Joel >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Thu, Mar 1, 2012 at 11:55 AM, Minh <minh...@telus.net> wrote: >>>>>>> >>>>>>>> You can try spitting out the results to a file so you can observe >>>>>>>> the hitch more closely. >>>>>>>> Look for a function called COM_Log >>>>>>>> >>>>>>>> COM_Log ( "viewangle_hitch.txt", "%.2f %.2f %.2f \n", >>>>>>>> viewangles.x, viewangles.y, viewangles.z ); >>>>>>>> >>>>>>>> On 3/1/2012 3:55 AM, Craig Louie wrote: >>>>>>>> >>>>>>>> Thanks for the reply Saul. I hadn't thought of disabling >>>>>>>> prediction. I just gave it a shot. I changed to "engine->ClientCmd( >>>>>>>> "cl_predict 0" );" in cdll_client_int.cpp. With another test, the >>>>>>>> unsmooth >>>>>>>> rotation when looking straight up/down still occurs. >>>>>>>> >>>>>>>> My main theories at this point: >>>>>>>> 1) Something is occurring in VectorAngles(vec_for_out, vec_up_out, >>>>>>>> viewangles) to cause this. VectorAngles() might not produce straight >>>>>>>> up/down Euler angles properly - choking because of aliasing perhaps? >>>>>>>> This >>>>>>>> is a big guess because I don't know the inner workings of >>>>>>>> VectorAngles(). >>>>>>>> 2) There is some code somewhere else that is conflicting with the >>>>>>>> full, unclamped rotation I've implemented. I've tried to remove all >>>>>>>> instances of pitch clamping, for example. But I may have missed >>>>>>>> something. >>>>>>>> Also, it's possible mouse rotation is somehow conflicting with my >>>>>>>> changes >>>>>>>> to joystick rotation. >>>>>>>> >>>>>>>> Here's a video of the issue I'm seeing. It happens a few times in >>>>>>>> the video. You'll see it happen the first time at about 11 seconds in >>>>>>>> when >>>>>>>> the text on the floor twists/shakes. >>>>>>>> http://www.youtube.com/watch?v=PLN641Qsn08 >>>>>>>> >>>>>>>> Thanks! >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Wed, Feb 29, 2012 at 11:34 PM, Saul Rennison < >>>>>>>> saul.renni...@gmail.com> wrote: >>>>>>>> >>>>>>>>> The hitching is most likely something trying to revert your angle >>>>>>>>> changes (I.e. in prediction). Have you tried disabling prediction? >>>>>>>>> >>>>>>>>> >>>>>>>>> On Thursday, March 1, 2012, Craig Louie wrote: >>>>>>>>> >>>>>>>>>> Hello Coders, >>>>>>>>>> >>>>>>>>>> I'm trying to create a space flight combat game with the Source >>>>>>>>>> SDK. Currently, I am trying to achieve rotation around the player's >>>>>>>>>> local >>>>>>>>>> axes for airplane-like pitch, yaw and roll. Below is the code I'm >>>>>>>>>> using to >>>>>>>>>> try to implement full 3D rotation. I'm running into a problem where >>>>>>>>>> the >>>>>>>>>> player's view twists and hitches unsmoothly when the player looks >>>>>>>>>> straight >>>>>>>>>> up or straight down. I think this may be because of the inherent >>>>>>>>>> problem of >>>>>>>>>> aliasing/Gimbal-lock when using Euler angles. Any advise? >>>>>>>>>> >>>>>>>>>> //######################################### >>>>>>>>>> //Take the Euler angles for the player's orientation (viewangles) >>>>>>>>>> and convert them to vectors. >>>>>>>>>> Vector vec_for, vec_rt, vec_up, vec_for_out, vec_rt_out, >>>>>>>>>> vec_up_out; >>>>>>>>>> AngleVectors(viewangles, &vec_for, &vec_rt, &vec_up); >>>>>>>>>> >>>>>>>>>> //Take the resulting vectors and the desired rotation amounts and >>>>>>>>>> convert them to Quaternions. >>>>>>>>>> Quaternion turn_q, look_q, roll_q; >>>>>>>>>> // NOTE: Assumes axis is a unit vector, non-unit vectors will >>>>>>>>>> bias the resulting rotation angle (but not the axis) >>>>>>>>>> VectorNormalize(vec_up); >>>>>>>>>> AxisAngleQuaternion(vec_up, turn_angle, turn_q); >>>>>>>>>> >>>>>>>>>> VectorNormalize(vec_rt); >>>>>>>>>> AxisAngleQuaternion(vec_rt, look_angle, look_q); >>>>>>>>>> >>>>>>>>>> VectorNormalize(vec_for); >>>>>>>>>> AxisAngleQuaternion(vec_for, roll_angle, roll_q); >>>>>>>>>> >>>>>>>>>> //Convert the quaternions to matrices. >>>>>>>>>> matrix3x4_t xform0, xform1, xform2; >>>>>>>>>> QuaternionMatrix(turn_q, xform0); >>>>>>>>>> QuaternionMatrix(look_q, xform1); >>>>>>>>>> QuaternionMatrix(roll_q, xform2); >>>>>>>>>> >>>>>>>>>> //Combine matrices. >>>>>>>>>> matrix3x4_t xformA, xformB; >>>>>>>>>> MatrixMultiply(xform0, xform1, xformA); >>>>>>>>>> MatrixMultiply(xformA, xform2, xformB); >>>>>>>>>> >>>>>>>>>> //Rotate the vectors with our combined rotation matrix. >>>>>>>>>> VectorRotate(vec_for, xformB, vec_for_out); >>>>>>>>>> VectorRotate(vec_rt, xformB, vec_rt_out); >>>>>>>>>> VectorRotate(vec_up, xformB, vec_up_out); >>>>>>>>>> >>>>>>>>>> //Determine the new viewangles based on our rotated vectors. >>>>>>>>>> VectorAngles(vec_for_out, vec_up_out, viewangles); >>>>>>>>>> //######################################### >>>>>>>>>> >>>>>>>>>> I put this code into in_joystick.cpp in the JoyStickMove( float >>>>>>>>>> frametime, CUserCmd *cmd ) function. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Thanks! >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> >>>>>>>>> >>>>>>>>> Kind regards, >>>>>>>>> *Saul Rennison* >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> To unsubscribe, edit your list preferences, or view the list >>>>>>>>> archives, please visit: >>>>>>>>> https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> To unsubscribe, edit your list preferences, or view the list archives, >>>>>>>> please >>>>>>>> visit:https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> To unsubscribe, edit your list preferences, or view the list >>>>>>>> archives, please visit: >>>>>>>> https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> To unsubscribe, edit your list preferences, or view the list >>>>>> archives, please visit: >>>>>> https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders >>>>>> >>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> To unsubscribe, edit your list preferences, or view the list archives, >>>>> please visit: >>>>> https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders >>>>> >>>>> >>>>> >>>> >>>> >>>> -- >>>> -Tony >>>> >>>> >>>> _______________________________________________ >>>> To unsubscribe, edit your list preferences, or view the list archives, >>>> please visit: >>>> https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders >>>> >>>> >>>> >>> >>> _______________________________________________ >>> To unsubscribe, edit your list preferences, or view the list archives, >>> please visit: >>> https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders >>> >>> >>> >> > > _______________________________________________ > To unsubscribe, edit your list preferences, or view the list archives, > please visit: > https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders > > >
_______________________________________________ To unsubscribe, edit your list preferences, or view the list archives, please visit: https://list.valvesoftware.com/cgi-bin/mailman/listinfo/hlcoders