Welcome to the Oculus Developer Forums!

Your participation on the forum is subject to the Oculus Code of Conduct.

In general, please be respectful and kind. If you violate the Oculus Code of Conduct, your access to the developer forums may be revoked at the discretion of Oculus staff.

[0.4.3] Head rotation pivot

tubeliartubeliar Posts: 9
NerveGear
edited January 2015 in Unity Development
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:
forward_And_Right.png

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:
Backward.png

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.

Comments

  • cyberealitycybereality Posts: 26,156 Oculus Staff
    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
  • tubeliartubeliar Posts: 9
    NerveGear
    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.
  • vrdavebvrdaveb Posts: 1,596 Oculus Staff
    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.
  • tubeliartubeliar Posts: 9
    NerveGear
    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;
    
  • viewportviewport Posts: 82
    Hiro Protagonist
    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.
  • BLACKISHBLACKISH Posts: 45 Oculus Start Member
    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)
  • vrdavebvrdaveb Posts: 1,596 Oculus Staff
    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]);
    
Sign In or Register to comment.