-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathLowLatencyTrackingManager.cs
143 lines (118 loc) · 5.39 KB
/
LowLatencyTrackingManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-FileCopyrightText: Copyright 2023 Reality Design Lab <[email protected]>
// SPDX-FileContributor: Yuchen Zhang <[email protected]>
// SPDX-License-Identifier: MIT
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.ARFoundation;
using UnityEngine.InputSystem.XR;
namespace HoloKit
{
/// <summary>
/// The script responsible for the low latency tracking feature, which communicates with
/// the native low latency tracking system and updates the camera pose accordingly.
/// </summary>
public class LowLatencyTrackingManager : MonoBehaviour
{
InputDevice m_InputDevice;
/// <summary>
/// The native pointer of the native low latency tracking system instance.
/// </summary>
IntPtr m_Ptr;
private ARCameraManager m_ARCameraManager;
#if UNITY_IOS && !UNITY_EDITOR
private void Start()
{
m_ARCameraManager = FindFirstObjectByType<ARCameraManager>();
if (m_ARCameraManager == null)
{
Debug.LogWarning("[LowLatencyTrackingManager] Failed to find ARCameraManager in the scene.");
return;
}
List<InputDevice> devices = new();
InputDevices.GetDevicesWithCharacteristics(InputDeviceCharacteristics.TrackedDevice, devices);
if (devices.Count > 0)
m_InputDevice = devices[0];
if (m_InputDevice == null)
{
Debug.LogWarning("[LowLatencyTrackingManager] Failed to find InputDevice.");
return;
}
var holoKitCameraManager = FindFirstObjectByType<HoloKitCameraManager>();
if (holoKitCameraManager == null)
{
Debug.LogWarning("[LowLatencyTrackingManager] Failed to find HoloKitCameraManager in the scene.");
return;
}
holoKitCameraManager.OnScreenRenderModeChanged += OnScreenRenderModeChanged;
m_Ptr = Init();
InitHeadTracker(m_Ptr);
PauseHeadTracker(m_Ptr);
}
#endif
#if UNITY_IOS && !UNITY_EDITOR
private void OnDestroy()
{
Delete(m_Ptr);
}
#endif
private void Update() {}
#if UNITY_IOS
private void OnScreenRenderModeChanged(ScreenRenderMode renderMode)
{
if (renderMode == ScreenRenderMode.Stereo)
{
m_ARCameraManager.frameReceived += OnFrameReceived;
Application.onBeforeRender += OnBeforeRender;
ResumeHeadTracker(m_Ptr);
}
else
{
m_ARCameraManager.frameReceived -= OnFrameReceived;
Application.onBeforeRender -= OnBeforeRender;
PauseHeadTracker(m_Ptr);
}
}
private void OnFrameReceived(ARCameraFrameEventArgs args)
{
bool isPositionValid = m_InputDevice.TryGetFeatureValue(CommonUsages.centerEyePosition, out Vector3 position) || m_InputDevice.TryGetFeatureValue(CommonUsages.colorCameraPosition, out position);
bool isRotationValid = m_InputDevice.TryGetFeatureValue(CommonUsages.centerEyeRotation, out Quaternion rotation) || m_InputDevice.TryGetFeatureValue(CommonUsages.colorCameraRotation, out rotation);
if (isPositionValid && isRotationValid)
{
float[] positionArr = new float[] { position.x, position.y, position.z };
float[] rotationArr = new float[] { rotation.x, rotation.y, rotation.z, rotation.w };
AddSixDoFData(m_Ptr, (long)args.timestampNs, positionArr, rotationArr);
}
}
private void OnBeforeRender()
{
UpdateHeadTrackerPose();
}
private void UpdateHeadTrackerPose()
{
float[] positionArr = new float[3];
float[] rotationArr = new float[4];
GetHeadTrackerPose(m_Ptr, positionArr, rotationArr);
Vector3 position = new(positionArr[0], positionArr[1], positionArr[2]);
Quaternion rotation = new(rotationArr[0], rotationArr[1], rotationArr[2], rotationArr[3]);
transform.SetPositionAndRotation(position, rotation);
}
[DllImport("__Internal", EntryPoint = "HoloKit_LowLatencyTracking_init")]
static extern IntPtr Init();
[DllImport("__Internal", EntryPoint = "HoloKit_LowLatencyTracking_initHeadTracker")]
static extern void InitHeadTracker(IntPtr self);
[DllImport("__Internal", EntryPoint = "HoloKit_LowLatencyTracking_pauseHeadTracker")]
static extern void PauseHeadTracker(IntPtr self);
[DllImport("__Internal", EntryPoint = "HoloKit_LowLatencyTracking_resumeHeadTracker")]
static extern void ResumeHeadTracker(IntPtr self);
[DllImport("__Internal", EntryPoint = "HoloKit_LowLatencyTracking_addSixDoFData")]
static extern void AddSixDoFData(IntPtr self, long timestamp, [In] float[] position, [In] float[] orientation);
[DllImport("__Internal", EntryPoint = "HoloKit_LowLatencyTracking_getHeadTrackerPose")]
static extern void GetHeadTrackerPose(IntPtr self, [Out] float[] position, [Out] float[] orientation);
[DllImport("__Internal", EntryPoint = "HoloKit_LowLatencyTracking_delete")]
static extern void Delete(IntPtr self);
#endif
}
}