Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved XR Hands Package Only Support OpenXR Provider Implementation?

Discussion in 'XR Interaction Toolkit and Input' started by Xxxxxxxu, Oct 20, 2023.

  1. Xxxxxxxu

    Xxxxxxxu

    Joined:
    Aug 1, 2017
    Posts:
    12
    I have a plan to implement my own XR Hands native provider-plugin.

    The XR Hands package homepage at https://docs.unity3d.com/Packages/com.unity.xr.hands@1.1/manual/index.html?q=XR%20Hand#samples states that "Currently, the OpenXR package is the only plug-in provider that supports hand tracking."

    Therefore, I would like to confirm whether it is currently the only way for UnityXR has an integration with an OpenXR-based provider in order to support XR Hands, or if there is a way to directly implement XR Hands like the way does on InputSubsystem or DisplaySubsystem.
     
    Last edited: Oct 20, 2023
  2. Xxxxxxxu

    Xxxxxxxu

    Joined:
    Aug 1, 2017
    Posts:
    12
  3. Xxxxxxxu

    Xxxxxxxu

    Joined:
    Aug 1, 2017
    Posts:
    12
    Hi, @VRDave_Unity
    In this thread I find your answer about you have been working on the Oculus-specific provider for the subsystem.

    My question is about is there a way for me(an XR-Device-Provider with naive codes and hardware) to have a chance to implement the native hand provider on my own without supporting OpenXR, and finally the XR Hand Package's HandSubsystem works base on my provider-plugin.
     
  4. unity_andrewc

    unity_andrewc

    Unity Technologies

    Joined:
    Dec 14, 2015
    Posts:
    202
    See https://docs.unity3d.com/Packages/com.unity.xr.hands@1.1/manual/implement-a-provider.html for a start. You'll need to implement this: https://docs.unity3d.com/Packages/c...erImplementation.XRHandSubsystemProvider.html (mentioned in the previous link). I need to add to the docs in the first link that in your loader, you should also store a XRHandProviderUtility.SubsystemUpdater (in the UnityEngine.XR.Hands.ProviderImplementation namespace) in your loader to create it when you create the subsystem, start it when you start the subsystem, stop it when you stop the subsystem, and destroy it when you destroy the subsystem.

    Also, if you're passing the NativeArray memory for joints down to native code to get filled out (via GetUnsafePtr()) instead of creating them with XRHandProviderUtility.CreateJoint (also in the UnityEngine.XR.Hands.ProviderImplementation namespace), you'll need to mimic the source of XRHandJoint.cs in both struct order/sizing and the logic for treating the most significant bit of the ID field as a bool for whether it's on the right hand.
     
  5. Xxxxxxxu

    Xxxxxxxu

    Joined:
    Aug 1, 2017
    Posts:
    12
    @unity_andrewc, thank you very much for your replay, that helps me start to clarify my thoughts.

    Can I understand it this way:

    When I'm implementing the Provider for InputSubsystem and Provider for DisplaySubsystem, the entire lifecycle of calls and binding between C# and Native (Subsystem of C#, Provider of C#, Provider Partial of Native) is handled by Unity, so I can directly connect to the interfaces defined in "IUnityXRInput.h" and "IUnityXRDisplay.h" in Native to complete the Provider of Native.

    However, when performing gesture operations, I cannot find the corresponding interface file (similar to IUnityXRHand.h, is it exists?) in Native. According to your reply, I should start from the Provider of C# and use the Hand subsystem API provided by Unity to obtain my platform-specific gesture/hand data in Native. In other words, the encapsulation starts from Unity, not from Native, unlike Input and Display which start from Native.
     
  6. unity_andrewc

    unity_andrewc

    Unity Technologies

    Joined:
    Dec 14, 2015
    Posts:
    202
    You're right that the encapsulation starts from Unity in C# for something like the hand subsystem, as opposed to in native headers and plug-in code like with the display and input subsystems.

    There are two kinds of subsystems - those that can be defined in packages, and those that have to be defined as part of the core Unity product. The hand subsystem is the former, while display and input are the latter. There are some ways this affects writing a provider:
    • For subsystems like the hand subsystem, all code is in C# until the provider uses something like the DllImport property to call into their native plugin. For subsystems like display and input, there's still a C# way of calling into the subsystem that Unity defines, but all code for a provider is native unless the provider decides to call into managed code on their own (not typically done, but I don't see the harm in it).
    • A result of the above bullet point is that the interface you work with to provide data to the subsystem is in a different setup and language. For subsystems like the hand subsystem, you just need to work in C# to implement the provider and, where needed, call into your own native code - all definitions of anything you need to work with is in C#, and unless you're providing platform-specific data, you just need to worry about the provider type (the subsystemTypeOverride is entirely optional). For subsystems like the display and input subsystems, the corresponding interface is entirely in native code, in the headers you mentioned (IUnityXRDisplay.h, for example). The corresponding file(s) to IUnityFoo.h for subsystems like the hand subsystem are where-ever the package-writer chose to place it in C#, but you'll find it somewhere in the runtime folder of that package (Subsystem, Provider, Descriptor). The corresponding type to UnityXRFooProvider in an IUnityXRFoo.h that you need to implement as a provider is the XRFooSubsystemProvider type in C# for hand-like subsystems. There is no corresponding hand-subsystem-like C# version of an IUnityXRFooInterface, however - C# providers cannot call back into their subsystems like display-/input-like providers can.
    • The way the descriptor gets registered - and therefore available in a call to SubsystemManager.GetSubsystemDescriptors<TFooSubsystem>() to find the descriptor you want and call Create() on it to get the subsystem - is different between these kinds of subsystems. For the hand subsystem kind, the way this is done is with a call to TFooSubsystemDescriptor.Register() during a
      [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]-decorated method, (see https://docs.unity3d.com/Packages/c...provider.html#register-a-subsystem-descriptor). For the kind of subsystem that display and input both are, the way this is done is by having a UnitySubsystemsManifest.json that core Unity will read at start-up automatically to populate the descriptors itself.
    • Also, there's no such thing for subsystems like the hand subsystem as something that corresponds to a separate RegisterLifecycleProvider call in native-land. The corresponding calls are in the base provider type (Start, Stop, and Destroy, while Create really exists on the descriptor).
    Also, to answer another of your questions, there is no such thing as IUnityXRHands.h or anything like it due to this difference between kinds of subsystems.
     
    Xxxxxxxu likes this.
  7. Xxxxxxxu

    Xxxxxxxu

    Joined:
    Aug 1, 2017
    Posts:
    12
    @unity_andrewc
    Thank you so much for your answer, which gave me a systematic understanding of XRSubsystem and XRProvider. I can now begin working on the Hands. Thanks again, have a nice day.
     
    unity_andrewc and ericprovencher like this.