Search Unity

Resolved ARFoundation ArAnchor nativePtr needs extra conversion for OpenXR

Discussion in 'AR' started by Duckyyy, Nov 17, 2021.

  1. Duckyyy

    Duckyyy

    Joined:
    Jan 2, 2015
    Posts:
    4
    For my HoloLens application I'm using the AR Foundation AR Anchor. In unity 2020.3.13f1 and versions below I can use the nativePtr of that anchor to grab the internal pointer. In 2021.2.2f1 the application crashes right after using the pointer underlying values.

    So first I created this struct as referenced in the Extending AR Foundation guide.
    upload_2021-11-22_15-57-36.png

    This nativepointer is cast to this UnityAnchorPointer struct via the Marhsal.PtrToStructure method.
    upload_2021-11-22_15-58-11.png

    After getting the struct I can cast the pointer to the platform anchor I can cast it to a SpatialAnchor, with which I can do whatever I want.
    upload_2021-11-22_15-58-32.png

    This works fine in Unity 2020 and below.
    For example the result string of the IntPtr of the anchor is 1471842069840 (called "platformPointer" in the picture)
    Where the result of the version number of the anchor is 1 (called "UnityInternal" in the picture).

    However when I run the exact same code in Unity 2021 the platform anchor reference is always 29 and the version number is 1821066133505. Of course with the anchor IntPtr being 29 the app crashes when it tries to call the GetObjectForIUnknown function.

    After running the apps a few times it seems like in 2020 the version is static, being 1 (which makes sense). In 2021 the anchor pointer seems to be static, being 29. Since that makes no sense, I have tried to swap the anchor pointer and the version pointer around, without any luck.

    The exact unity version I'm testing it on right now are:
    - 2020.3.13f1 - working
    - 2021.2.2f1 - NOT working

    It seems to me that somehow with the version change either the LayoutKind.Sequential doesn't work in the same way or that the nativePtr of AR Foundation has changed.
     
    Last edited: Nov 22, 2021
    KyryloKuzyk likes this.
  2. Duckyyy

    Duckyyy

    Joined:
    Jan 2, 2015
    Posts:
    4
    Regarding the vesion number pointer, when I log it as a int32 it seems to always return 1 again, even in unity 2021.

    upload_2021-11-22_15-55-4.png

    So it seems that I'm not able to use that information to check the validity of the pointer data.

    Edit:
    Just for record keeping.

    If I grab the native pointer via the ARAnchorManager the nativePtr references a different address. upload_2021-11-22_16-3-47.png
    When using this pointer instead the app still crashes on the Marshal.GetObjectForIUnknown call, so sadly this doesn't solve the problem.
     
    Last edited: Nov 22, 2021
  3. Duckyyy

    Duckyyy

    Joined:
    Jan 2, 2015
    Posts:
    4
  4. Duckyyy

    Duckyyy

    Joined:
    Jan 2, 2015
    Posts:
    4
    I figured out the issue. In 2020 I had setup the project to use the Windows MR plugin:
    upload_2021-11-22_17-57-42.png

    While in 2021 it's setup to use the OpenXR Plugin.

    upload_2021-11-22_17-58-16.png

    With OpenXR I can use the Microsoft.MixedReality.OpenXR.AnchorConverter class to get the spatial anchor. This makes a call to the OpenXR api to convert the handle to the windows anchor handle ("openxr_plugin_TryAcquirePerceptionSpatialAnchor").

    upload_2021-11-22_18-25-46.png

    At this moment I'm not able to dive deeper into the Mixed Reality Open XR Plugin to find out what that code does exactly.
     
  5. keveleigh

    keveleigh

    Official Microsoft Employee

    Joined:
    Jun 19, 2015
    Posts:
    35
    The important thing to know is that it basically uses the MSFT extensions for anchor interop described at https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_MSFT_perception_anchor_interop.

    Also, as far as the conversion from the `nativePtr` to a struct, Mixed Reality OpenXR passes out the `NativeAnchorData` struct found in AnchorSubsystem.cs in the package (currently `internal`, but maybe we need to make it `public` for ease of use):

    [StructLayout(LayoutKind.Sequential, Pack = 8)]
    internal struct NativeAnchorData
    {
    public uint version; // == 1
    public ulong anchorHandle; // OpenXR XrSpatialAnchor handle
    }