-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVRInitializer.cs
184 lines (159 loc) · 6.05 KB
/
VRInitializer.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
using System.Collections;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Management;
using Warudo.Core.Utils;
namespace QTExtensions.VR
{
/// <summary>
/// Component that handles setting up the VR camera and structures.
/// </summary>
public class VRInitializer : MonoBehaviour
{
private Camera customVRCamera;
private Transform cameraHolder;
private Vector3 positionOffset;
private Vector3 rotationOffset;
private bool showAvatar;
private float nearClipPlane;
private bool useNativeTracking;
// Structure is Anchor (tracked object)
// |- CameraHolder (transform for offsets)
// |- CustomVRCamera (actual camera and native tracking space)
private void LateUpdate()
{
// Early exit if no tracking or not setup yet
if (!useNativeTracking) { return; }
if (cameraHolder == null && customVRCamera == null) { return; }
// Find native headset and move the camera with it
var device = InputDevices.GetDeviceAtXRNode(UnityEngine.XR.XRNode.Head);
if (device.isValid)
{
if (device.TryGetFeatureValue(CommonUsages.devicePosition, out var devicePosition))
{
customVRCamera.transform.localPosition = devicePosition;
}
if (device.TryGetFeatureValue(CommonUsages.deviceRotation, out var deviceRotation))
{
customVRCamera.transform.localRotation = deviceRotation;
}
}
}
/// <summary>
/// Start the VR systems.
/// </summary>
public void SetupVR()
{
StartCoroutine(StartXRCoroutine());
}
/// <summary>
/// Stops the VR systems.
/// </summary>
public void StopVR()
{
Debug.Log("Stopping XR");
// If it's still not available, then nothing to do
if (XRGeneralSettings.Instance.Manager.activeLoader != null)
{
Debug.Log("DBQT " + XRGeneralSettings.Instance.Manager.isInitializationComplete);
XRGeneralSettings.Instance.Manager.StopSubsystems();
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
}
}
/// <summary>
/// Creates the camera structure and set it up for VR.
/// </summary>
public void SetupCamera(Transform anchor)
{
// Delete existing vr camera
CleanUpCameras();
// Make sure none of existing cameras will render to VR
var allCameras = GameObject.FindObjectsOfType<Camera>();
foreach (var cam in allCameras)
{
cam.stereoTargetEye = StereoTargetEyeMask.None;
}
cameraHolder = new GameObject("VRCameraHolder").transform;
cameraHolder.transform.SetParent(anchor);
var vrCamObj = new GameObject("VRCamera");
customVRCamera = vrCamObj.AddComponent<Camera>();
customVRCamera.transform.SetParent(cameraHolder);
UpdateSettingsInternal();
}
/// <summary>
/// Destroys all the generated camera objects.
/// </summary>
public void CleanUpCameras()
{
if (customVRCamera != null)
{
Destroy(customVRCamera.gameObject);
customVRCamera = null;
}
if (cameraHolder != null)
{
Destroy(cameraHolder.gameObject);
cameraHolder = null;
}
}
/// <summary>
/// Applies updated settings to the VR camera.
/// </summary>
public void UpdateSettings(Vector3 positionOffset, Vector3 rotationOffset, bool showAvatar, float nearClipPlane, bool useNativeTracking)
{
this.positionOffset = positionOffset;
this.rotationOffset = rotationOffset;
this.showAvatar = showAvatar;
this.nearClipPlane = nearClipPlane;
this.useNativeTracking = useNativeTracking;
UpdateSettingsInternal();
}
private void UpdateSettingsInternal()
{
if (cameraHolder != null)
{
cameraHolder.transform.localPosition = this.positionOffset;
cameraHolder.transform.localEulerAngles = this.rotationOffset;
}
if (customVRCamera != null)
{
customVRCamera.nearClipPlane = nearClipPlane;
customVRCamera.stereoTargetEye = StereoTargetEyeMask.Both;
customVRCamera.clearFlags = CameraClearFlags.Skybox;
var characterLayer = LayerMask.NameToLayer("Character");
if (showAvatar)
{
customVRCamera.AddLayerToCullingMask(characterLayer);
}
else
{
customVRCamera.RemoveLayerFromCullingMask(characterLayer);
}
if (!useNativeTracking)
{
customVRCamera.transform.localPosition = Vector3.zero;
customVRCamera.transform.localRotation = Quaternion.identity;
}
}
}
private IEnumerator StartXRCoroutine()
{
Debug.Log("Initializing XR");
// Initialize if loader isn't active
if (XRGeneralSettings.Instance.Manager.activeLoader == null)
{
yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
}
// If it's still not available, then something is failing
if (XRGeneralSettings.Instance.Manager.activeLoader == null)
{
Debug.LogWarning("Initializing XR Failed");
}
else
{
Debug.Log("Starting XR");
XRGeneralSettings.Instance.Manager.StartSubsystems();
}
}
}
}