microsoft / MixedRealityToolkit-Unity

This repository is for the legacy Mixed Reality Toolkit (MRTK) v2. For the latest version of the MRTK please visit https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity
https://aka.ms/mrtkdocs
MIT License
6.01k stars 2.12k forks source link

UnityEngine.XR.XRDevice.GetNativePtr() always return IntPtr.Zero #9183

Closed Namithia20 closed 3 years ago

Namithia20 commented 3 years ago

Overview

I'm trying execute this code on Hololens 2 applying SceneUnderstanding SDK, but the method UnityEngine.XR.XRDevice.GetNativePtr() always return IntPtr.Zero.

¿There is other way to get a NativePtr?

IntPtr nativeStruct = UnityEngine.XR.XRDevice.GetNativePtr();           
if (nativeStruct != IntPtr.Zero) 
{
      HolograhicFrameData holoFrameData = Marshal.PtrToStructure<HolograhicFrameData>(nativeStruct);
      SpatialCoordinateSystem unityCoordinateSystem = SpatialCoordinateSystem.FromNativePtr(holoFrameData.ISpatialCoordinateSystemPtr);
      SpatialCoordinateSystem sceneCoordinateSystem = SpatialGraphInteropPreview.CreateCoordinateSystemForNode(scene.OriginSpatialGraphNodeId);
      sceneToUnityTransform = sceneCoordinateSystem.TryGetTransformTo(unityCoordinateSystem);
}

Setup

Unity Version 2020.2 MRTK Version 2.5.3 OpenXR Plugin 0.1.2 Windows XR Plugin 4.2.1 XR Plugin Management 4.0.0-pre.2

keveleigh commented 3 years ago

Windows XR Plugin 4.2.1

Using Unity new XR SDK plugin, this API returning IntPtr.Zero is expected. I can't find the exact Unity forum post anymore, but one of their engineers mentioned that this is intentional.

If you're looking for the underlying SpatialCoordinateSystem, you can use a different API: the OriginSpatialCoordinateSystem under https://docs.unity.cn/Packages/com.unity.xr.windowsmr@2.6/api/UnityEngine.XR.WindowsMR.WindowsMREnvironment.html

Note that this only works for the Windows XR Plugin. If you're using OpenXR, we'd have to find another way.

Namithia20 commented 3 years ago

Thanks, but now I have a new problem on Hololens 2 Device. When the app is running on device I recibe the next error: "Unable to load DLL WindowsMRXRSDK: the specified module could not found".

¿Windows XR Plugin its not compatible with UWP? ¿Are there any alternative with OpenXR?

keveleigh commented 3 years ago

Windows XR Plugin its not compatible with UWP

It definitely is! Are there any other logs around the DLL load issue? What package version are you using? What architecture are you building (ARM vs ARM64)? Early releases of Windows XR Plugin didn't support ARM, but anything recent should be fine.

Namithia20 commented 3 years ago

That error it's show on run time on Device, like an exception. In Editor it don't show any error/log about DLLs. The architecture for building is ARM64 (I always use that for Hololens 2). My setup is:

Namithia20 commented 3 years ago

Hi, finaly I'm solved the DLL WindowsMRXRSDK error (Im not sure how excatly, because I tried a lot of changes.).

In Visual Studio, I'm installed all abailables versions of Windows SDK (I was desperated). I'm back de XR plugin to version 3.2.16 (removing OpenXR too) and the Windows XR plugin to version 3.4.0 I uninstalled MSBuild too and I rebuilded the proyect step by step.

Actualy, my setup is:

Unity Version 2020.2 MRTK version 2.5.3 Window XR plugin 3.4.0 XR Plugin Management 3.2.16

With all that, it's works. :) One thousand of thanks @keveleigh !

Now, it's not necesary using the structure 'holoFrameData' and 'Marshal.PtrToStructure()'.

Old code:

IntPtr nativeStruct = UnityEngine.XR.XRDevice.GetNativePtr();           
if (nativeStruct != IntPtr.Zero) 
{
      HolograhicFrameData holoFrameData = Marshal.PtrToStructure<HolograhicFrameData>(nativeStruct);
      SpatialCoordinateSystem unityCoordinateSystem = SpatialCoordinateSystem.FromNativePtr(holoFrameData.ISpatialCoordinateSystemPtr);
      SpatialCoordinateSystem sceneCoordinateSystem = SpatialGraphInteropPreview.CreateCoordinateSystemForNode(scene.OriginSpatialGraphNodeId);
      sceneToUnityTransform = sceneCoordinateSystem.TryGetTransformTo(unityCoordinateSystem);
}

New code:

IntPtr nativePtr = WindowsMREnvironment.OriginSpatialCoordinateSystem;    

if (nativeStruct != IntPtr.Zero) 
{
      SpatialCoordinateSystem unityCoordinateSystem = SpatialCoordinateSystem.FromNativePtr(nativePtr);
      SpatialCoordinateSystem sceneCoordinateSystem = SpatialGraphInteropPreview.CreateCoordinateSystemForNode(scene.OriginSpatialGraphNodeId);
      sceneToUnityTransform = sceneCoordinateSystem.TryGetTransformTo(unityCoordinateSystem);
}
chrisnasseh commented 2 years ago

Windows XR Plugin 4.2.1

Using Unity new XR SDK plugin, this API returning IntPtr.Zero is expected. I can't find the exact Unity forum post anymore, but one of their engineers mentioned that this is intentional.

If you're looking for the underlying SpatialCoordinateSystem, you can use a different API: the OriginSpatialCoordinateSystem under https://docs.unity.cn/Packages/com.unity.xr.windowsmr@2.6/api/UnityEngine.XR.WindowsMR.WindowsMREnvironment.html

Note that this only works for the Windows XR Plugin. If you're using OpenXR, we'd have to find another way.

I have looked at so many different forums but still can't find a way to get the IntPtr value in OpenXR for the Coordinate System. Could anyone help me with that?

The original line of code was: // WorldOriginPtr = UnityEngine.XR.WindowsMR.WindowsMREnvironment.OriginSpatialCoordinateSystem;

When I write // WorldOriginPtr = SpatialLocator.GetDefault().CreateStationaryFrameOfReferenceAtCurrentLocation().CoordinateSystem;

I get a compilation error that says implicit conversion to IntPtr isn't possible.

keveleigh commented 2 years ago

@chrisnasseh For OpenXR, you can use https://docs.microsoft.com/dotnet/api/microsoft.mixedreality.openxr.perceptioninterop.getscenecoordinatesystem?view=mixedreality-openxr-plugin-1.4#microsoft-mixedreality-openxr-perceptioninterop-getscenecoordinatesystem(unityengine-pose) with Pose.identity as the parameter.

chrisnasseh commented 2 years ago

with Pose.identity as the parameter

the line of code I have found relating to that is // SpatialCoordinateSystem WorldOriginPtr = Microsoft.MixedReality.OpenXR.PerceptionInterop.GetSceneCoordinateSystem(UnityEngine.Pose.identity) as SpatialCoordinateSystem;

I believe this is from one of the issues you replied to a while ago.

However, I just want to make sure that WorldOriginPtr is being given the IntPtr for the Origin of this Coordinate System. I hope this makes sense.

keveleigh commented 2 years ago

with Pose.identity as the parameter

the line of code I have found relating to that is // SpatialCoordinateSystem WorldOriginPtr = Microsoft.MixedReality.OpenXR.PerceptionInterop.GetSceneCoordinateSystem(UnityEngine.Pose.identity) as SpatialCoordinateSystem;

I believe this is from one of the issues you replied to a while ago.

However, I just want to make sure that WorldOriginPtr is being given the IntPtr for the Origin of this Coordinate System. I hope this makes sense.

In this API, we don't pass the IntPtr but the object itself. Once you cast it to a SpatialCoordinateSystem, you should be good to go! If you specifically need the IntPtr for your scenario, let me know and I can look into retrieving that.

chrisnasseh commented 2 years ago

If you specifically need the IntPtr for your scenario, let me know and I can look into retrieving that.

Since I am working on an environment that was written with the Legacy XR in mind, the entire script relies on the IntPtr for WorldOrigin coordinates. If it is possible to find that, it would allow me to adapt the entire code to OpenXR. Thanks in advance.

huangzejie0810 commented 1 year ago

@chrisnasseh对于 OpenXR,您可以使用https://docs.microsoft.com/dotnet/api/microsoft.mixedreality.openxr.perceptioninterop.getscenecoordinatesystem?view=mixedreality-openxr-plugin-1.4#microsoft-mixedreality-openxr-perceptioninterop-getscenecoordinatesystem( unityengine-pose)Pose.identity作为参数。

Pose.identity参数为

我发现与此相关的代码行是 我相信这是您刚才回复的问题之一。 但是,我只是想确保 WorldOriginPtr 被赋予 IntPtr 作为该坐标系的原点。我希望这是有道理的。

在这个 API 中,我们不传递 theIntPtr而是传递 theobject本身。一旦你将它投射到 a SpatialCoordinateSystem,你应该可以开始了!如果您特别需要IntPtr您的场景,请告诉我,我可以考虑检索它。

UnityEngine.XR.XRDevice.GetNativePtr() return IntPtr.Zero。 I also encountered the same problem, I use unity version is 2021.3.5, May I ask how to finally how to solve, thank you!