ViveSoftware / ViveInputUtility-Unity

A toolkit that helps developing/prototyping VR apps.
http://u3d.as/uF7
Other
352 stars 82 forks source link

Rotaional and positional offset between Vive and Rift controllers #135

Open wirelessdreamer opened 4 years ago

wirelessdreamer commented 4 years ago

I've done testing with both openVR, and oculus software between vive and rift hardware. It looks like there is a 35 degree rotational offset between controller orientation, and some positional offset.

Good example of a controller setup for Rift S image

To match a vive controller in about the same position requires: image

I remember having a talk in a bug with someone at HTC in the past year or so on this. I finally started digging into it now, and couldn't find what bug that conversation was going on it. Let me know what you need or what ideas your have in this area. Up till now i've been maintaining seperate bindings per platform. and its a ton of work now that there is rift cv1, rift s, vive, mixed reality, quest, quest through virtual desktop. its just unmaininable having to work around every new controller setup, instead of the sdk aligning everything the same.

wirelessdreamer commented 4 years ago

another straight forward way to reproduce this: The controller model for the CV1 doesn't match up to the physical location of the controller. it has the same positional offset as is mentioned above of how far a child gameobject is off from its parent.

Both tests were done with both Oculus utilities and SteamVR setup with Vive input utility. Oculus was set first in the list of XR devices in the player panel.

wirelessdreamer commented 4 years ago

here is the workaround I use for this issue if anyone else is fighting with it I put it on the Gameobject with VivePoseTracker

using HTC.UnityPlugin.Vive; using HTC.UnityPlugin.VRModuleManagement; using UnityEngine;

[RequireComponent(typeof(VivePoseTracker))] public class VRControllerInit : MonoBehaviour { VivePoseTracker vivePoseTracker;

private void Start() {
    vivePoseTracker = GetComponent<VivePoseTracker>();    
}

public void ApplyControllerOffset() {
    //Debug.Log("Using driver for vr: " + UnityEngine.XR.XRSettings.loadedDeviceName);
    if(VRModule.GetDeviceState(0).deviceModel == VRModuleDeviceModel.ViveHMD) {
        vivePoseTracker.rotOffset = new Vector3(0, 0, 0);
        vivePoseTracker.posOffset = new Vector3(0, 0, 0);
    } else if(VRModule.GetDeviceState(0).deviceModel == VRModuleDeviceModel.OculusHMD && UnityEngine.XR.XRSettings.loadedDeviceName == "Oculus") {
        vivePoseTracker.rotOffset = new Vector3(-30, 0, 0);
        vivePoseTracker.posOffset = new Vector3(0, 0.02f, 0.05f);
    }
}

}

wirelessdreamer commented 4 years ago

Call ApplyControllerOffset() from OnIsValidChanged

It handles if your using oculus plugin, and oculus devices through steamvr

wirelessdreamer commented 4 years ago

I just saw this in OVRManager.cs included with the oculus utilities, and it applies to this issue. image

wirelessdreamer commented 3 years ago

Controller models still don't match up between OpenVR and Oculus drivers? has any official solution been found to this, having to create seperate locations for all controllers based on platform is a huge pain.

wirelessdreamer commented 3 years ago

Expected behavior, weather loading with OpenVR or Oculus driver, the controller model should show up to match the physical controller.

luizcarlosfx commented 3 years ago

I have the same problem with oculus and Windows Mixed Reality. Seems like steam vr handles controller poses in a different way than the other brands. I'd really love to know how to have a unified way to get device position then apply to the model and have the same results device independent

wirelessdreamer commented 3 years ago

@luizcarlosfx this is my local fix:

private void Start() { if(XRSettings.loadedDeviceName == "OpenVR") { StartCoroutine(ApplyOffset()); } }

IEnumerator ApplyOffset() {
    yield return new WaitForSeconds(0.5f);
    Debug.Log("Detected OpenVR, applying offset");
    VivePoseTracker vpt = transform.GetComponentInParent<VivePoseTracker>();
    vpt.rotOffset = new Vector3(40, 0, 0);
    vpt.posOffset = new Vector3(0, 0.05f, -0.08f);
}
luizcarlosfx commented 3 years ago

@luizcarlosfx this is my local fix:

private void Start() { if(XRSettings.loadedDeviceName == "OpenVR") { StartCoroutine(ApplyOffset()); } }

IEnumerator ApplyOffset() {
    yield return new WaitForSeconds(0.5f);
    Debug.Log("Detected OpenVR, applying offset");
    VivePoseTracker vpt = transform.GetComponentInParent<VivePoseTracker>();
    vpt.rotOffset = new Vector3(40, 0, 0);
    vpt.posOffset = new Vector3(0, 0.05f, -0.08f);
}

Thanks for your solution, but I was trying to fix this in a more generic way. I have the same problem with windows mixed reality device. When I was using steamvr none of this problems happened, so I'm looking to find how do they implement the solution.