Skip to main content
Participant
October 27, 2014

[0.4.3] Head rotation pivot

When rotating your head with DK1 or with DK2 but without positional tracking a neck model is applied to incorporate some natural movement. It is however not clear where the pivot is. You would think you can just centre the rig on where you want the rotation point to be but the actual pivot seems to be behind it. To illustrate, looking forward the eye cameras are beside the rig. Rotating right you see the eyes move back and their position with respect to the rig changes:


If you rotate all the way to look behind you you see the effect best. I added some debug lines to show the distance from their original center:


This is not a problem until you put the rig on an avatar. Starting out your head is above the neck. But when you look off center, suddenly you are floating beside your body, even if it rotates with you! This is even the case in Tuscany which i used to make the screenshots, but there it isn't visible because your body has no mesh. You could see it because the camera position changes with respect to the collider, so looking at different angles you can come a little bit closer to things.

So experimentally i found that the pivot seems to lie about 0.06 units behind the camera rig's position, give or take. But why is it there? The neck measurements from the config utility are 0.075 units vertical and 0.0805 units horizontal. As an aside, it's unclear how you would get these values. The statements below both return defaults, even if i change them in the config util:
OVRManager.capiHmd.GetFloat(Hmd.OVR_KEY_NECK_TO_EYE_DISTANCE, Hmd.OVR_DEFAULT_NECK_TO_EYE_VERTICAL);
OVRManager.capiHmd.GetFloat(Hmd.OVR_KEY_EYE_TO_NOSE_DISTANCE, Hmd.OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL);


But, even if i leave them at the defaults then how would i use them to compute where the real pivot is? Or is there some other function i'm missing? In my specific case i don't minde the head floating off because the user leans in any direction, but i do mind the head changing position with respect to the body when all you do is rotate your head.
    This topic has been closed for replies.

    7 replies

    Inspiring
    October 27, 2014
    I think what you are seeing is normal.

    The head rotates from the base of the neck, which is physically further back than the center of the eye balls.

    Hope that makes sense.
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
    tubeliarAuthor
    Participant
    October 27, 2014
    Yes, i know about the neck model so i know this is how it's supposed to behave. The problem is that i don't know where to put the camera rig so that the pivot is where i need it to be. I can put it at 0.06 units in front but that is just en estimate. And furthermore it will be incorrect if someone adjusts the values with the config utility.
    Inspiring
    October 29, 2014
    The OVRCameraRig GameObject is at the initial center eye position. You can query the neck-to-eye offset as follows:
    var neckOffset = new float[2] {OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, OVR_DEFAULT_NECK_TO_EYE_VERTICAL};
    neckOffset = OVRManager.capiHmd.GetFloatArray(OVR_KEY_NECK_TO_EYE_DISTANCE, neckOffset);


    Then your pivot (the neck position) will be at
    new Vector3(0f, -neckOffset[1], -neckOffset[2])
    in OVRCameraRig's local space.
    tubeliarAuthor
    Participant
    November 3, 2014
    Excellent! Exactly what i needed, thank you! :D
    I needed to prepend the key names with the Hmd class and the array indexing was 1 and 0 (instead of 1 and 2) but it works. This is how i use it:
    using Ovr;
    ...
    float[] neckOffset = new float[]{Hmd.OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, Hmd.OVR_DEFAULT_NECK_TO_EYE_VERTICAL};
    neckOffset = OVRManager.capiHmd.GetFloatArray(Hmd.OVR_KEY_NECK_TO_EYE_DISTANCE, neckOffset);
    Vector3 neck = new Vector3(0, neckOffset[1], neckOffset[0]);
    cameraRig.transform.localPosition = neck;
    Inspiring
    November 15, 2014
    "tubeliar" wrote:
    Excellent! Exactly what i needed, thank you! :D
    I needed to prepend the key names with the Hmd class and the array indexing was 1 and 0 (instead of 1 and 2) but it works. This is how i use it:
    using Ovr;
    ...
    float[] neckOffset = new float[]{Hmd.OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, Hmd.OVR_DEFAULT_NECK_TO_EYE_VERTICAL};
    neckOffset = OVRManager.capiHmd.GetFloatArray(Hmd.OVR_KEY_NECK_TO_EYE_DISTANCE, neckOffset);
    Vector3 neck = new Vector3(0, neckOffset[1], neckOffset[0]);
    cameraRig.transform.localPosition = neck;


    I was looking for a way to get rid of the neck model, and rotate based on the center pivot of the stereoscopic cameras. I use to use scale down OVRCameraRig, but now it reduce my IPD in the same proportion and now I have no control of IPD as I use to have. Unfortunately I have a limited scripting knowledge so standar Unity tools hacks, or scripts already developed has been my way so far.

    It would be so useful to get control of the rotation Pivot, as well as Camera tracker Pivot.
    Up and Coming
    December 15, 2014
    Okay. This gives me a good position for the neck, but if I lean or move away, the neck stays where it was while my eyes move on.

    Is there a way to get a neck position from the Hmd that's always where it's supposed to be?
    BLACKISH (Games) | GameAssets.net (Assets)
    Inspiring
    January 3, 2015
    If you want to use the head model to estimate the neck's location when position tracking is enabled, try this:
    float[] neckOffset = new float[]{Hmd.OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, Hmd.OVR_DEFAULT_NECK_TO_EYE_VERTICAL};
    neckOffset = OVRManager.capiHmd.GetFloatArray(Hmd.OVR_KEY_NECK_TO_EYE_DISTANCE, neckOffset);
    Vector3 neckTracked = rig.centerEyeAnchor.localPosition - rig.centerEyeAnchor.localRotation * new Vector3(0, neckOffset[1], neckOffset[0]);