Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
yog's avatar
yog
Honored Guest
13 years ago

Math problem / oculus "extreme" rotation

Hello !

I am having a "simple" math problem on oculus integration on CryEngine (orignal code is not written by myself), and I am looking for a clean solution, that I have trouble to find by myself.

I am trying to fix a bug, that invert Pitch once the player has turn about 180 degree - In that case, looking up makes the player look down.
I am using the following code.
The idea is to get the the delta orientation each frame, and combine that delta in the "final" listener function, combining mouse infos and OVR data.



	Quat sCurrentOrientation(m_pDevice->GetOrientation());
m_PreviousOrientation.Invert();
Quat sDeltaOrientation(sCurrentOrientation*m_PreviousOrientation);
m_PreviousOrientation=sCurrentOrientation;

Ang3 sDelta(sDeltaOrientation);
{
//send x, y, z to input listener
}

//with :
virtual Quat GetOrientation() const { OVR::Quatf q = m_senFusion.GetOrientation(); return Quat(q.w, q.x, q.y, q.z); }



and, later, in the player input function :

	
Ang3 deltaRotation = m_deltaRotation * mouseSensitivity * generalSensitivity; //"mouse movement"

deltaRotation += m_HMD_deltaRotation; // combine mouse movement and Oculus data


That seems ok to me, but once turned back of 180 degree, the Pitch is reverted.

Anyone knows how to fix this ?

9 Replies

  • yog's avatar
    yog
    Honored Guest
    No, only oculus, mouse works fine all the time ..
  • I'm not familiar with cry engine, but rather than using euler angles as I assume you are, have you tried converting your euler angles to a quaternion then multiplying them instead. Euler angles have the ability to cause gimbal lock, which is what you are describing, which is why quaternions are useful when combining rotations. but once again I'm unfamiliar with cryengine.
  • yog's avatar
    yog
    Honored Guest
    "genetransfer" wrote:
    I'm not familiar with cry engine, but rather than using euler angles as I assume you are, have you tried converting your euler angles to a quaternion then multiplying them instead. Euler angles have the ability to cause gimbal lock, which is what you are describing, which is why quaternions are useful when combining rotations. but once again I'm unfamiliar with cryengine.


    Well, that's what the code si doing actually :/

      Quat sCurrentOrientation(m_pDevice->GetOrientation());
    m_PreviousOrientation.Invert();
    Quat sDeltaOrientation(sCurrentOrientation*m_PreviousOrientation);
    m_PreviousOrientation=sCurrentOrientation;


    Euler angles are used in the end, just to tell the mouse how to move.
    However, I also tried replacing Ang3 by the Quat values (sDeltaOrientation) directly, and the same thing happened...
  • As I'm unfamiliar with cryengine, I don't know what setting the mouse is for or why you need that.

    are you trying to use the mouse to orientate the player and or camera on yaw and/or pitch and then add the oculus orientation to that?

    if so in my engine I do this, you may be able to use it as "pseudo code" if crytek has similar functions...(if I misunderstood what you are trying to achieve I apologise.)

    D3DXVECTOR2 MP;//mouse position
    D3DXQUATERNION q1;//orientation representing mouse orientation applied to camera
    D3DXQUATERNION q2;//oculus orientation
    D3DXQUATERNION q3;//final orientation

    Mp = iMouseLookLimits();//a function returning the mouse coords as euler angles
    iQuaternionFromEulerAngles(&q1,/*Mp.x*/0.0f,Mp.y,0.0f);//create quat for controlling camera yaw
    //if want camera to pitch with mouse also uncomment Mp.x
    iOculusRiftOrientation(&q2);//get the orientation of the rift
    iQuaternionMultiply(&q3,&q2,&q1);//multiply mouse and oculus orientations
    iCameraOrientationSet(Camera,&q3);//apply to camera
  • The inverted pitch is due to CryEngine using a different coordinate system than the oculus sdk (see documentation of both the oculus sdk and cryengine). You'll have to map the axes of the quaternion returned by the oculus to the axes used by cryengine. X-Axis stays the same while the cryengine Y-Axis is the negative Z-Axis of oculus sdk and the cryengine Z-Axis is the oculus' Y-Axis.

    cryQuat.v.x = OculusQuat.x
    cryQuat.v.y = -OculusQuat.z
    cryQuat.v.z = OculusQuat.y
    cryQuat.w = OculusQuat.w