Skip to main content
Up and Coming
September 7, 2014

Head offset

G'day,

DK2 arrived and I have been mucking around with it and the latest UE4 binary build and have come across a little problem - the head offset.

At the moment, impossible to aim correctly while wearing a Rift. Its offsets the location of the camera after it has been adjusted in-game to line up with the weapon sights correctly.

In earlier versions of the Oculus Plugin, you could control the head offset via a config variable:
[Oculus.Settings]
HeadModel_v2=(X=0.0,Y=0,Z=0.0)


In the latest version, this is no longer the case.
Needless to say, this is very frustrating.

This has been mentioned before, but I'll say it too - I don't want anything to be done automatically for me.

Please give game developers the control needed to make the best possible experiences.

Thank you.
    This topic has been closed for replies.

    42 replies

    Up and Coming
    November 24, 2014
    By default, nothing changes the location of the camera component apart from its attachment point (socket, bone, spring arm etc).

    At least I can't see anything that does :)
    Rule#21: Be polite, be professional, but have a plan to kill everyone you meet.
    Up and Coming
    November 28, 2014
    It seems like a strange way to go about things, but I think I can make it work. I've been rewriting my project from scratch in 4.5.1 over the last 2 nights.
    I complain a lot. Just think of me as a squeaky wheel lol. Youtube channel -> https://www.youtube.com/user/xblBlackFang/videos
    Up and Coming
    December 1, 2014
    I'm not making any progress. As soon as I press alt+enter to put the window in the rift, my view detaches itself from its socket and starts doing whatever the Oculus plugin wants it to do...

    I've commented out the bodies of UpdatePlayerViewPoint, ApplyHmdRotation, and UpdatePlayerCameraRotation, but the Rift still hijacks my view. If I could locate where the hijack was ocurring, I could modify it to do math for my animations and the camera in the same place, but comments in OculusRift.cpp are sparse to say the least.

    EDIT: Ok, I found it. It seems to happen in CalculateStereoViewOffset;

    //const FVector vHMDPosition = DeltaControlOrientation.RotateVector(CurHmdPosition);
    //ViewLocation += vHMDPosition;

    Commenting out those lines prevents the hijack.
    I complain a lot. Just think of me as a squeaky wheel lol. Youtube channel -> https://www.youtube.com/user/xblBlackFang/videos
    Up and Coming
    December 4, 2014
    Create your own player camera manager and in your version of
    APlayerCameraManager::UpdateViewTarget(), change this:

    if (bFollowHmdOrientation)
    {
    if (GEngine->HMDDevice.IsValid() && GEngine->HMDDevice->IsHeadTrackingAllowed())
    {
    GEngine->HMDDevice->UpdatePlayerCameraRotation(this, OutVT.POV);
    }
    }


    To this:

    if (bFollowHmdOrientation)
    {
    if (GEngine->HMDDevice.IsValid() && GEngine->HMDDevice->IsHeadTrackingAllowed())
    {
    FVector ViewForward, ViewRight, ViewUp;
    FRotationMatrix(OutVT.POV.Rotation).GetScaledAxes(ViewForward, ViewRight, ViewUp);

    GEngine->HMDDevice->UpdatePlayerCameraRotation(this, OutVT.POV);

    FQuat OrientationAsQuat;
    FVector Position(0.0f);

    GEngine->HMDDevice->GetCurrentOrientationAndPosition(OrientationAsQuat, Position);

    OutVT.POV.Location -= (Position.X * ViewForward);
    OutVT.POV.Location -= (Position.Y * ViewRight);
    OutVT.POV.Location -= (Position.Z * ViewUp);
    }
    }


    And see what happens.

    This is slightly different to my implementation, which uses a custom view rotation variable instead of controller rotation.
    Rule#21: Be polite, be professional, but have a plan to kill everyone you meet.
    Up and Coming
    December 12, 2014
    Just FYI: I haven't given up on this issue, I really need to find some time and think this through. Like I tried to explain earlier, there are a lot of variables here and one of the most important ones is latency. Therefore, a lot of stuff is happening 'automatically' (such as applying orientation/position to 'camera').
    Up and Coming
    December 14, 2014
    "artyom17" wrote:
    The GetCurrentOrientationAndPosition function returns current orientation and position offset from the zero point.


    How is this zero point determined?
    It is just using the pawn/character eye height?
    i.e. GetActorLocation() + FVector(0.0f, 0.0f, BaseEyeHeight);
    Rule#21: Be polite, be professional, but have a plan to kill everyone you meet.
    Up and Coming
    December 14, 2014
    This is described in our doc: http://static.oculus.com/sdk-downloads/documents/Oculus_Developer_Guide_0.4.3.pdf, chapter 7.1.1.
    By default, the "Zero point" is the origin point that is located one meter away from the camera in the direction of the optical axis but with the same height as the camera. The default origin orientation is level with the ground with the
    negative z axis pointing towards the camera. In other words, a headset yaw angle of zero corresponds to the
    user looking towards the camera (please, refer to the doc chapter 7.1.1 for a pic).
    The zero point location got corrected once ResetPosition() (or ResetOrientationAndPosition()) function is called; in this case, the current location of the headset becomes a 'zero point'.
    An example. Let assume your head is located in the point of origin in the tracking camera frustum (again, see the doc, chapter 7.1.1). In this case GetCurrentOrientationAndPosition will return FVector(0,0,0). Now you shift you head to the right by 10 cm (assuming World2Meters scale is 100). The newly reported position will be FVector(0, 0.10*100, 0). Left 10 cm - FVector(0, -0.10*100, 0) (assuming there is no rotation; if there was rotation then the returned vector is rotated as well).
    In the case, if you used ResetPosition / ResetOrientationAndPosition, the current HMD position (at the moment of the reset function call) is saved as BaseOffset and it is used to correct the returned vector by subtracting BaseOffset from the position to be returned (effectively bringing the 'zero point' to that location).
    Up and Coming
    December 15, 2014
    Ok.
    A bit confused, as what I've just read and what is happening doesn't make sense.

    If I understand correctly, if the I place my DK2 down on the table so it doesn turn or move, then load up the game, the only difference between the VR and non-VR view should be the offset for each eye position?
    Rule#21: Be polite, be professional, but have a plan to kill everyone you meet.
    Up and Coming
    December 15, 2014
    "KrisRedbeard" wrote:
    Ok.
    A bit confused, as what I've just read and what is happening doesn't make sense.

    If I understand correctly, if the I place my DK2 down on the table so it doesn turn or move, then load up the game, the only difference between the VR and non-VR view should be the offset for each eye position?


    Uhm....In the case if your headset was in field of view of the tracker camera then PosB (your have the headset picked up) minus PosA (the headset is laying on a table) will give you the offset. But the PosB and PosA themselves will represent offsets from the origin point, which is fixed to 1m from the tracker camera (see the doc, chapter 7.1.1).
    Up and Coming
    December 15, 2014
    Just go to FOculusRiftHMD::GetCurrentPose function (file Engine/Plugins/Runtime/OculusRift/Source/Private/OculusRiftHMD.cpp) and uncomment the following line:

    UE_LOG(LogHMD, Log, TEXT("P: %.3f %.3f %.3f"), CurrentPosition.X, CurrentPosition.Y, CurrentPosition.Y);

    Replace the 'CurrentPosition' by the 'CurrentHmdPosition', build and run (in VS Debugger). Check what is being printed in the Debug Output, while you are moving the headset in front of the tracker camera.

    Note, I've corrected my previous reply: when you shift to the right you get Y change to plus, left - Y change to minus (previously I mistakenly used X -axis). Also used wrong units (should be 0.1 instead of 10 for 10 cm).

    P.S. Seems like we need to document this moment well. Noted.