diff --git a/Assets/Scripts/Catalog.prefab b/Assets/Scripts/Catalog.prefab
new file mode 100644
index 0000000..e6ab31d
--- /dev/null
+++ b/Assets/Scripts/Catalog.prefab
@@ -0,0 +1,245 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1527984575184472642
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1527984575184472644}
+ - component: {fileID: 1527984575184472645}
+ m_Layer: 0
+ m_Name: Catalog
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1527984575184472644
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1527984575184472642}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 2.0397532, y: 1.6641229, z: -1.5216272}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 6652929519105104434}
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1527984575184472645
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1527984575184472642}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 6e448cbb02ada1545b6c4c79341232fc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ maxShownObjects: 6
+ angle: 130
+ distance: 0.17
+ objectScale: 0.04
+--- !u!1 &6275806258134515848
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 6652929519105104434}
+ - component: {fileID: 3102087200456469538}
+ - component: {fileID: 3086371222807627863}
+ - component: {fileID: 7945404223398940130}
+ - component: {fileID: 5004594542533833549}
+ - component: {fileID: 1321968106976948543}
+ - component: {fileID: 3556194868201819980}
+ m_Layer: 0
+ m_Name: Sphere
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &6652929519105104434
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6275806258134515848}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.04, y: 0.04, z: 0.04}
+ m_ConstrainProportionsScale: 1
+ m_Children: []
+ m_Father: {fileID: 1527984575184472644}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &3102087200456469538
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6275806258134515848}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: b93b6a877adcbf94c89a9d6e0c0e844d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ activateActionSetOnAttach:
+ actionSetPath:
+ hideHandOnAttach: 1
+ hideSkeletonOnAttach: 0
+ hideControllerOnAttach: 0
+ handAnimationOnPickup: 0
+ setRangeOfMotionOnPickup: -1
+ useHandObjectAttachmentPoint: 1
+ attachEaseIn: 0
+ snapAttachEaseInCurve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ - serializedVersion: 3
+ time: 1
+ value: 1
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0
+ outWeight: 0
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ snapAttachEaseInTime: 0.15
+ snapAttachEaseInCompleted: 0
+ skeletonPoser: {fileID: 0}
+ handFollowTransform: 1
+ highlightOnHover: 1
+ hideHighlight: []
+ hoverPriority: 0
+--- !u!114 &3086371222807627863
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6275806258134515848}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 783750eec4c41da428b7651515146d14, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ velocityAverageFrames: 5
+ angularVelocityAverageFrames: 11
+ estimateOnAwake: 0
+--- !u!114 &7945404223398940130
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6275806258134515848}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: e7418c7dd8f977d4e969202d3fa7e926, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ poseEditorExpanded: 1
+ blendEditorExpanded: 1
+ poseNames:
+ - sphereSmallPose (MAIN)
+ overridePreviewLeftHandPrefab: {fileID: 1000013348574242, guid: 638779290bce1af49b356f33dcc6fccf, type: 3}
+ overridePreviewRightHandPrefab: {fileID: 1000010304998954, guid: 6def53d002137b747aec0b29551e0e25, type: 3}
+ skeletonMainPose: {fileID: 11400000, guid: ccd16738d1f943640aa2aed1071a3897, type: 2}
+ skeletonAdditionalPoses: []
+ showLeftPreview: 0
+ showRightPreview: 0
+ previewLeftInstance: {fileID: 0}
+ previewRightInstance: {fileID: 0}
+ previewPoseSelection: 0
+ blendingBehaviours: []
+ scale: 1
+--- !u!33 &5004594542533833549
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6275806258134515848}
+ m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &1321968106976948543
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6275806258134515848}
+ m_Enabled: 1
+ m_CastShadows: 1
+ m_ReceiveShadows: 1
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 2
+ m_RayTraceProcedural: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+ m_AdditionalVertexStreams: {fileID: 0}
+--- !u!135 &3556194868201819980
+SphereCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6275806258134515848}
+ m_Material: {fileID: 0}
+ m_IsTrigger: 0
+ m_Enabled: 1
+ serializedVersion: 2
+ m_Radius: 0.5
+ m_Center: {x: 0, y: 0, z: 0}
diff --git a/Assets/Scripts/Catalog.prefab.meta b/Assets/Scripts/Catalog.prefab.meta
new file mode 100644
index 0000000..b2ef51b
--- /dev/null
+++ b/Assets/Scripts/Catalog.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 1805c511e7b7f0e49afb0651e27725b4
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRPackageInstaller.cs b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRPackageInstaller.cs
new file mode 100644
index 0000000..774a5f5
--- /dev/null
+++ b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRPackageInstaller.cs
@@ -0,0 +1,470 @@
+#if (UNITY_EDITOR && UNITY_2019_1_OR_NEWER)
+
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Unity.XR.OpenVR.SimpleJSON;
+using UnityEditor;
+using UnityEditor.PackageManager;
+using UnityEditor.PackageManager.Requests;
+using UnityEditor.PackageManager.UI;
+using UnityEngine;
+using UnityEngine.Networking;
+
+namespace Unity.XR.OpenVR
+{
+ [InitializeOnLoad]
+ public class OpenVRPackageInstaller : ScriptableObject
+ {
+ private const string valveOpenVRPackageString = "com.valvesoftware.unity.openvr";
+
+
+ private static ListRequest listRequest;
+ private static AddRequest addRequest;
+
+ private static System.Diagnostics.Stopwatch packageTime = new System.Diagnostics.Stopwatch();
+ private const float estimatedTimeToInstall = 90; // in seconds
+
+ private const string updaterKeyTemplate = "com.valvesoftware.unity.openvr.updateState.{0}";
+ private static string updaterKey
+ {
+ get { return string.Format(updaterKeyTemplate, Application.productName); }
+ }
+
+ private static UpdateStates updateState
+ {
+ get { return _updateState; }
+ set
+ {
+#if VALVE_DEBUG
+ Debug.Log("[DEBUG] Update State: " + value.ToString());
+#endif
+ _updateState = value;
+ EditorPrefs.SetInt(updaterKey, (int)value);
+ }
+ }
+ private static UpdateStates _updateState = UpdateStates.Idle;
+
+ private static double runningSeconds
+ {
+ get
+ {
+ if (packageTime.IsRunning == false)
+ packageTime.Start();
+ return packageTime.Elapsed.TotalSeconds;
+ }
+ }
+
+ private static bool forced = false;
+
+ public static void Start(bool force = false)
+ {
+ EditorApplication.update -= Update;
+ EditorApplication.update += Update;
+
+ if (force)
+ {
+ RemoveScopedRegistry();
+ }
+ }
+
+ static OpenVRPackageInstaller()
+ {
+ #if OPENVR_XR_API //if we're updating, go ahead and just start
+ Start();
+ #endif
+ }
+
+ ///
+ /// State Machine
+ /// Idle: Start from last known state. If none is known, ask user if they want to install, if yes goto remove scoped registry step
+ /// WaitingOnExistingCheck:
+ /// RemoveScopedRegistry: Remove the scoped registry entry if it exists
+ /// WaitingForAdd: if the add request has been nulled or completed successfully, request a list of packages for confirmation
+ /// WaitingForAddConfirmation: enumerate the packages and verify the add succeeded. If it failed, try again.
+ /// If it succeeded request removal of this script
+ /// RemoveSelf: delete the key that we've been using to maintain state. Delete this script and the containing folder if it's empty.
+ ///
+ private static void Update()
+ {
+ switch (updateState)
+ {
+ case UpdateStates.Idle:
+ if (EditorPrefs.HasKey(updaterKey))
+ {
+ _updateState = (UpdateStates)EditorPrefs.GetInt(updaterKey);
+ packageTime.Start();
+ }
+ else
+ {
+ RequestExisting();
+ }
+ break;
+
+ case UpdateStates.WaitingOnExistingCheck:
+ if (listRequest == null)
+ {
+ //the list request got nulled for some reason. Request it again.
+ RequestExisting();
+ }
+ else if (listRequest != null && listRequest.IsCompleted)
+ {
+ if (listRequest.Error != null || listRequest.Status == UnityEditor.PackageManager.StatusCode.Failure)
+ {
+ DisplayErrorAndStop("Error while checking for an existing OpenVR package.", listRequest);
+ }
+ else
+ {
+ if (listRequest.Result.Any(package => package.name == valveOpenVRPackageString))
+ {
+ var existingPackage = listRequest.Result.FirstOrDefault(package => package.name == valveOpenVRPackageString);
+
+ string latestTarball = GetLatestTarballVersion();
+
+ if (latestTarball != null && latestTarball.CompareTo(existingPackage.version) == 1)
+ {
+ //we have a tarball higher than the currently installed version
+ string upgradeString = string.Format("This SteamVR Unity Plugin has a newer version of the Unity XR OpenVR package than you have installed. Would you like to upgrade?\n\nCurrent: {0}\nUpgrade: {1} (recommended)", existingPackage.version, latestTarball);
+ bool upgrade = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Updater", upgradeString, "Upgrade", "Cancel");
+ if (upgrade)
+ RemoveScopedRegistry();
+ else
+ {
+ bool delete = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Updater", "Would you like to remove this updater script so we don't ask again?", "Remove updater", "Keep");
+ if (delete)
+ {
+ Stop();
+ return;
+ }
+ else
+ {
+ GentleStop();
+ return;
+ }
+ }
+ }
+ }
+ else
+ {
+ #if UNITY_2020_1_OR_NEWER
+ RemoveScopedRegistry(); //just install if we're on 2020 and they don't have the package
+ return;
+ #else
+ //they don't have the package yet. Ask if they want to install (only for 2019)
+ bool blankInstall = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Installer", "The SteamVR Unity Plugin can be used with the legacy Unity VR API (Unity 5.4 - 2019) or with the Unity XR API (2019+). Would you like to install OpenVR for Unity XR?", "Install", "Cancel");
+ if (blankInstall)
+ RemoveScopedRegistry();
+ else
+ {
+ bool delete = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Installer", "Would you like to remove this installer script so we don't ask again?", "Remove installer", "Keep");
+ if (delete)
+ {
+ Stop();
+ return;
+ }
+ else
+ {
+ GentleStop();
+ return;
+ }
+ }
+ #endif
+ }
+ }
+ }
+ break;
+
+ case UpdateStates.WaitingForAdd:
+ if (addRequest == null)
+ {
+ //the add request got nulled for some reason. Request an add confirmation
+ RequestAddConfirmation();
+ }
+ else if (addRequest != null && addRequest.IsCompleted)
+ {
+ if (addRequest.Error != null || addRequest.Status == UnityEditor.PackageManager.StatusCode.Failure)
+ {
+ DisplayErrorAndStop("Error adding new version of OpenVR package.", addRequest);
+ }
+ else
+ {
+ //verify that the package has been added (then stop)
+ RequestAddConfirmation();
+ }
+ }
+ else
+ {
+ if (packageTime.Elapsed.TotalSeconds > estimatedTimeToInstall)
+ DisplayErrorAndStop("Error while trying to add package.", addRequest);
+ else
+ DisplayProgressBar();
+ }
+ break;
+
+ case UpdateStates.WaitingForAddConfirmation:
+ if (listRequest == null)
+ {
+ //the list request got nulled for some reason. Request it again.
+ RequestAddConfirmation();
+ }
+ else if (listRequest != null && listRequest.IsCompleted)
+ {
+ if (listRequest.Error != null || listRequest.Status == UnityEditor.PackageManager.StatusCode.Failure)
+ {
+ DisplayErrorAndStop("Error while confirming the OpenVR package has been added.", listRequest);
+ }
+ else
+ {
+ if (listRequest.Result.Any(package => package.name == valveOpenVRPackageString))
+ {
+ updateState = UpdateStates.RemoveSelf;
+ UnityEditor.EditorUtility.DisplayDialog("OpenVR Unity XR Installer", "OpenVR Unity XR successfully installed.\n\nA restart of the Unity Editor may be necessary.", "Ok");
+ }
+ else
+ {
+ //try to add again if it's not there and we don't know why
+ RequestAdd();
+ }
+ }
+ }
+ else
+ {
+ if (runningSeconds > estimatedTimeToInstall)
+ {
+ DisplayErrorAndStop("Error while confirming the OpenVR package has been added.", listRequest);
+ }
+ else
+ DisplayProgressBar();
+ }
+ break;
+
+ case UpdateStates.RemoveSelf:
+ EditorPrefs.DeleteKey(updaterKey);
+ EditorUtility.ClearProgressBar();
+ EditorApplication.update -= Update;
+
+#if VALVE_SKIP_DELETE
+ Debug.Log("[DEBUG] skipping script deletion. Complete.");
+ return;
+#endif
+
+ var script = MonoScript.FromScriptableObject(OpenVRPackageInstaller.CreateInstance());
+ var path = AssetDatabase.GetAssetPath(script);
+ FileInfo updaterScript = new FileInfo(path); updaterScript.IsReadOnly = false;
+ FileInfo updaterScriptMeta = new FileInfo(path + ".meta");
+ FileInfo simpleJSONScript = new FileInfo(Path.Combine(updaterScript.Directory.FullName, "OpenVRSimpleJSON.cs"));
+ FileInfo simpleJSONScriptMeta = new FileInfo(Path.Combine(updaterScript.Directory.FullName, "OpenVRSimpleJSON.cs.meta"));
+
+ updaterScript.IsReadOnly = false;
+ updaterScriptMeta.IsReadOnly = false;
+ simpleJSONScript.IsReadOnly = false;
+ simpleJSONScriptMeta.IsReadOnly = false;
+
+ updaterScriptMeta.Delete();
+ if (updaterScriptMeta.Exists)
+ {
+ DisplayErrorAndStop("Error while removing package installer script. Please delete manually.", listRequest);
+ return;
+ }
+
+ simpleJSONScript.Delete();
+ simpleJSONScriptMeta.Delete();
+ updaterScript.Delete();
+
+ AssetDatabase.Refresh();
+ break;
+ }
+ }
+
+ private static string GetLatestTarballVersion()
+ {
+ FileInfo[] files;
+ FileInfo latest = GetAvailableTarballs(out files);
+
+ if (latest == null)
+ return null;
+
+ return GetTarballVersion(latest);
+ }
+
+ private static FileInfo GetAvailableTarballs(out FileInfo[] packages)
+ {
+ var installerScript = MonoScript.FromScriptableObject(OpenVRPackageInstaller.CreateInstance());
+ var scriptPath = AssetDatabase.GetAssetPath(installerScript);
+ FileInfo thisScript = new FileInfo(scriptPath);
+
+ packages = thisScript.Directory.GetFiles("*.tgz");
+
+ if (packages.Length > 0)
+ {
+ if (packages.Length > 1)
+ {
+ var descending = packages.OrderByDescending(file => file.Name);
+ var latest = descending.First();
+ packages = descending.Where(file => file != latest).ToArray();
+ return latest;
+ }
+
+ var onlyPackage = packages[0];
+ packages = new FileInfo[0];
+ return onlyPackage;
+ }
+ else
+ return null;
+ }
+
+ private static string GetTarballVersion(FileInfo file)
+ {
+ int startIndex = file.Name.IndexOf('-') + 1;
+ int endIndex = file.Name.IndexOf(".tgz");
+ int len = endIndex - startIndex;
+ return file.Name.Substring(startIndex, len);
+ }
+
+ private const string packageManifestPath = "Packages/manifest.json";
+ private const string scopedRegistryKey = "scopedRegistries";
+ private const string npmRegistryName = "Valve";
+
+ //load packages.json
+ //check for existing scoped registries
+ //check for our scoped registry
+ //if no to either then add it
+ //save file
+ //reload
+ private static void RemoveScopedRegistry()
+ {
+ updateState = UpdateStates.RemoveOldRegistry;
+ packageTime.Start();
+
+ if (File.Exists(packageManifestPath) == false)
+ {
+ Debug.LogWarning("[OpenVR Installer] Could not find package manifest at: " + packageManifestPath);
+
+ RequestAdd();
+ return;
+ }
+
+ string jsonText = File.ReadAllText(packageManifestPath);
+ JSONNode manifest = JSON.Parse(jsonText);
+
+ if (manifest.HasKey(scopedRegistryKey) == true)
+ {
+ if (manifest[scopedRegistryKey].HasKey(npmRegistryName))
+ {
+ manifest[scopedRegistryKey].Remove(npmRegistryName);
+
+ File.WriteAllText(packageManifestPath, manifest.ToString(2));
+ Debug.Log("[OpenVR Installer] Removed Valve entry from scoped registry.");
+ }
+ }
+
+ RequestAdd();
+ }
+
+ private static void RequestAdd()
+ {
+ updateState = UpdateStates.WaitingForAdd;
+
+ FileInfo[] oldFiles;
+ FileInfo latest = GetAvailableTarballs(out oldFiles);
+
+ if (latest != null)
+ {
+ if (oldFiles.Length > 0)
+ {
+ var oldFilesNames = oldFiles.Select(file => file.Name);
+ string oldFilesString = string.Join("\n", oldFilesNames);
+ bool delete = UnityEditor.EditorUtility.DisplayDialog("OpenVR XR Installer", "Would you like to delete the old OpenVR packages?\n\n" + oldFilesString, "Delete old files", "Keep");
+ if (delete)
+ {
+ foreach (FileInfo file in oldFiles)
+ {
+ FileInfo meta = new FileInfo(file.FullName + ".meta");
+ if (meta.Exists)
+ {
+ meta.IsReadOnly = false;
+ meta.Delete();
+ }
+
+ if (file.Exists)
+ {
+ file.IsReadOnly = false;
+ file.Delete();
+ }
+ }
+ }
+ }
+
+ string packagePath = latest.FullName;
+ if (packagePath != null)
+ {
+ string packageAbsolute = packagePath.Replace("\\", "/");
+ string packageRelative = packageAbsolute.Substring(packageAbsolute.IndexOf("/Assets/"));
+ string packageURI = System.Uri.EscapeUriString(packageRelative);
+ addRequest = UnityEditor.PackageManager.Client.Add("file:.." + packageURI);
+ }
+ else
+ {
+ updateState = UpdateStates.RemoveSelf;
+ }
+ }
+ }
+
+ private static void RequestAddConfirmation()
+ {
+ updateState = UpdateStates.WaitingForAddConfirmation;
+ listRequest = Client.List(true, true);
+ }
+
+ private static void RequestExisting()
+ {
+ updateState = UpdateStates.WaitingOnExistingCheck;
+ listRequest = Client.List(true, true);
+ }
+
+ private static string dialogText = "Installing OpenVR Unity XR package from local storage using Unity Package Manager...";
+
+ private static void DisplayProgressBar()
+ {
+ bool cancel = UnityEditor.EditorUtility.DisplayCancelableProgressBar("SteamVR", dialogText, (float)packageTime.Elapsed.TotalSeconds / estimatedTimeToInstall);
+ if (cancel)
+ Stop();
+ }
+
+ private static void DisplayErrorAndStop(string stepInfo, Request request)
+ {
+ string error = "";
+ if (request != null)
+ error = request.Error.message;
+
+ string errorMessage = string.Format("{0}:\n\t{1}\n\nPlease manually reinstall the package through the package manager.", stepInfo, error);
+
+ UnityEngine.Debug.LogError(errorMessage);
+
+ Stop();
+
+ UnityEditor.EditorUtility.DisplayDialog("OpenVR Error", errorMessage, "Ok");
+ }
+
+ private static void Stop()
+ {
+ updateState = UpdateStates.RemoveSelf;
+ }
+
+ private static void GentleStop()
+ {
+ EditorApplication.update -= Update;
+ }
+
+ private enum UpdateStates
+ {
+ Idle,
+ WaitingOnExistingCheck,
+ RemoveOldRegistry,
+ WaitingForAdd,
+ WaitingForAddConfirmation,
+ RemoveSelf,
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRPackageInstaller.cs.meta b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRPackageInstaller.cs.meta
new file mode 100644
index 0000000..4df3077
--- /dev/null
+++ b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRPackageInstaller.cs.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 538300977557ee34892368a50c97bdd6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRSimpleJSON.cs b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRSimpleJSON.cs
new file mode 100644
index 0000000..e60979b
--- /dev/null
+++ b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRSimpleJSON.cs
@@ -0,0 +1,1352 @@
+/* * * * *
+ * A simple JSON Parser / builder
+ * ------------------------------
+ *
+ * It mainly has been written as a simple JSON parser. It can build a JSON string
+ * from the node-tree, or generate a node tree from any valid JSON string.
+ *
+ * Written by Bunny83
+ * 2012-06-09
+ *
+ * Changelog now external. See Changelog.txt
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2019 Markus Göbel (Bunny83)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * * * * */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+
+namespace Unity.XR.OpenVR.SimpleJSON
+{
+ public enum JSONNodeType
+ {
+ Array = 1,
+ Object = 2,
+ String = 3,
+ Number = 4,
+ NullValue = 5,
+ Boolean = 6,
+ None = 7,
+ Custom = 0xFF,
+ }
+ public enum JSONTextMode
+ {
+ Compact,
+ Indent
+ }
+
+ public abstract partial class JSONNode
+ {
+ #region Enumerators
+ public struct Enumerator
+ {
+ private enum Type { None, Array, Object }
+ private Type type;
+ private Dictionary.Enumerator m_Object;
+ private List.Enumerator m_Array;
+ public bool IsValid { get { return type != Type.None; } }
+ public Enumerator(List.Enumerator aArrayEnum)
+ {
+ type = Type.Array;
+ m_Object = default(Dictionary.Enumerator);
+ m_Array = aArrayEnum;
+ }
+ public Enumerator(Dictionary.Enumerator aDictEnum)
+ {
+ type = Type.Object;
+ m_Object = aDictEnum;
+ m_Array = default(List.Enumerator);
+ }
+ public KeyValuePair Current
+ {
+ get
+ {
+ if (type == Type.Array)
+ return new KeyValuePair(string.Empty, m_Array.Current);
+ else if (type == Type.Object)
+ return m_Object.Current;
+ return new KeyValuePair(string.Empty, null);
+ }
+ }
+ public bool MoveNext()
+ {
+ if (type == Type.Array)
+ return m_Array.MoveNext();
+ else if (type == Type.Object)
+ return m_Object.MoveNext();
+ return false;
+ }
+ }
+ public struct ValueEnumerator
+ {
+ private Enumerator m_Enumerator;
+ public ValueEnumerator(List.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { }
+ public ValueEnumerator(Dictionary.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { }
+ public ValueEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; }
+ public JSONNode Current { get { return m_Enumerator.Current.Value; } }
+ public bool MoveNext() { return m_Enumerator.MoveNext(); }
+ public ValueEnumerator GetEnumerator() { return this; }
+ }
+ public struct KeyEnumerator
+ {
+ private Enumerator m_Enumerator;
+ public KeyEnumerator(List.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { }
+ public KeyEnumerator(Dictionary.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { }
+ public KeyEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; }
+ public string Current { get { return m_Enumerator.Current.Key; } }
+ public bool MoveNext() { return m_Enumerator.MoveNext(); }
+ public KeyEnumerator GetEnumerator() { return this; }
+ }
+
+ public class LinqEnumerator : IEnumerator>, IEnumerable>
+ {
+ private JSONNode m_Node;
+ private Enumerator m_Enumerator;
+ internal LinqEnumerator(JSONNode aNode)
+ {
+ m_Node = aNode;
+ if (m_Node != null)
+ m_Enumerator = m_Node.GetEnumerator();
+ }
+ public KeyValuePair Current { get { return m_Enumerator.Current; } }
+ object IEnumerator.Current { get { return m_Enumerator.Current; } }
+ public bool MoveNext() { return m_Enumerator.MoveNext(); }
+
+ public void Dispose()
+ {
+ m_Node = null;
+ m_Enumerator = new Enumerator();
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return new LinqEnumerator(m_Node);
+ }
+
+ public void Reset()
+ {
+ if (m_Node != null)
+ m_Enumerator = m_Node.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new LinqEnumerator(m_Node);
+ }
+ }
+
+ #endregion Enumerators
+
+ #region common interface
+
+ public static bool forceASCII = false; // Use Unicode by default
+ public static bool longAsString = false; // lazy creator creates a JSONString instead of JSONNumber
+ public static bool allowLineComments = true; // allow "//"-style comments at the end of a line
+
+ public abstract JSONNodeType Tag { get; }
+
+ public virtual JSONNode this[int aIndex] { get { return null; } set { } }
+
+ public virtual JSONNode this[string aKey] { get { return null; } set { } }
+
+ public virtual string Value { get { return ""; } set { } }
+
+ public virtual int Count { get { return 0; } }
+
+ public virtual bool IsNumber { get { return false; } }
+ public virtual bool IsString { get { return false; } }
+ public virtual bool IsBoolean { get { return false; } }
+ public virtual bool IsNull { get { return false; } }
+ public virtual bool IsArray { get { return false; } }
+ public virtual bool IsObject { get { return false; } }
+
+ public virtual bool Inline { get { return false; } set { } }
+
+ public virtual void Add(string aKey, JSONNode aItem)
+ {
+ }
+ public virtual void Add(JSONNode aItem)
+ {
+ Add("", aItem);
+ }
+
+ public virtual JSONNode Remove(string aKey)
+ {
+ return null;
+ }
+
+ public virtual JSONNode Remove(int aIndex)
+ {
+ return null;
+ }
+
+ public virtual JSONNode Remove(JSONNode aNode)
+ {
+ return aNode;
+ }
+
+ public virtual JSONNode Clone()
+ {
+ return null;
+ }
+
+ public virtual IEnumerable Children
+ {
+ get
+ {
+ yield break;
+ }
+ }
+
+ public IEnumerable DeepChildren
+ {
+ get
+ {
+ foreach (var C in Children)
+ foreach (var D in C.DeepChildren)
+ yield return D;
+ }
+ }
+
+ public virtual bool HasKey(string aKey)
+ {
+ return false;
+ }
+
+ public virtual JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
+ {
+ return aDefault;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ WriteToStringBuilder(sb, 0, 0, JSONTextMode.Compact);
+ return sb.ToString();
+ }
+
+ public virtual string ToString(int aIndent)
+ {
+ StringBuilder sb = new StringBuilder();
+ WriteToStringBuilder(sb, 0, aIndent, JSONTextMode.Indent);
+ return sb.ToString();
+ }
+ internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode);
+
+ public abstract Enumerator GetEnumerator();
+ public IEnumerable> Linq { get { return new LinqEnumerator(this); } }
+ public KeyEnumerator Keys { get { return new KeyEnumerator(GetEnumerator()); } }
+ public ValueEnumerator Values { get { return new ValueEnumerator(GetEnumerator()); } }
+
+ #endregion common interface
+
+ #region typecasting properties
+
+
+ public virtual double AsDouble
+ {
+ get
+ {
+ double v = 0.0;
+ if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out v))
+ return v;
+ return 0.0;
+ }
+ set
+ {
+ Value = value.ToString(CultureInfo.InvariantCulture);
+ }
+ }
+
+ public virtual int AsInt
+ {
+ get { return (int)AsDouble; }
+ set { AsDouble = value; }
+ }
+
+ public virtual float AsFloat
+ {
+ get { return (float)AsDouble; }
+ set { AsDouble = value; }
+ }
+
+ public virtual bool AsBool
+ {
+ get
+ {
+ bool v = false;
+ if (bool.TryParse(Value, out v))
+ return v;
+ return !string.IsNullOrEmpty(Value);
+ }
+ set
+ {
+ Value = (value) ? "true" : "false";
+ }
+ }
+
+ public virtual long AsLong
+ {
+ get
+ {
+ long val = 0;
+ if (long.TryParse(Value, out val))
+ return val;
+ return 0L;
+ }
+ set
+ {
+ Value = value.ToString();
+ }
+ }
+
+ public virtual JSONArray AsArray
+ {
+ get
+ {
+ return this as JSONArray;
+ }
+ }
+
+ public virtual JSONObject AsObject
+ {
+ get
+ {
+ return this as JSONObject;
+ }
+ }
+
+
+ #endregion typecasting properties
+
+ #region operators
+
+ public static implicit operator JSONNode(string s)
+ {
+ return new JSONString(s);
+ }
+ public static implicit operator string(JSONNode d)
+ {
+ return (d == null) ? null : d.Value;
+ }
+
+ public static implicit operator JSONNode(double n)
+ {
+ return new JSONNumber(n);
+ }
+ public static implicit operator double(JSONNode d)
+ {
+ return (d == null) ? 0 : d.AsDouble;
+ }
+
+ public static implicit operator JSONNode(float n)
+ {
+ return new JSONNumber(n);
+ }
+ public static implicit operator float(JSONNode d)
+ {
+ return (d == null) ? 0 : d.AsFloat;
+ }
+
+ public static implicit operator JSONNode(int n)
+ {
+ return new JSONNumber(n);
+ }
+ public static implicit operator int(JSONNode d)
+ {
+ return (d == null) ? 0 : d.AsInt;
+ }
+
+ public static implicit operator JSONNode(long n)
+ {
+ if (longAsString)
+ return new JSONString(n.ToString());
+ return new JSONNumber(n);
+ }
+ public static implicit operator long(JSONNode d)
+ {
+ return (d == null) ? 0L : d.AsLong;
+ }
+
+ public static implicit operator JSONNode(bool b)
+ {
+ return new JSONBool(b);
+ }
+ public static implicit operator bool(JSONNode d)
+ {
+ return (d == null) ? false : d.AsBool;
+ }
+
+ public static implicit operator JSONNode(KeyValuePair aKeyValue)
+ {
+ return aKeyValue.Value;
+ }
+
+ public static bool operator ==(JSONNode a, object b)
+ {
+ if (ReferenceEquals(a, b))
+ return true;
+ bool aIsNull = a is JSONNull || ReferenceEquals(a, null) || a is JSONLazyCreator;
+ bool bIsNull = b is JSONNull || ReferenceEquals(b, null) || b is JSONLazyCreator;
+ if (aIsNull && bIsNull)
+ return true;
+ return !aIsNull && a.Equals(b);
+ }
+
+ public static bool operator !=(JSONNode a, object b)
+ {
+ return !(a == b);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return ReferenceEquals(this, obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ #endregion operators
+
+ [ThreadStatic]
+ private static StringBuilder m_EscapeBuilder;
+ internal static StringBuilder EscapeBuilder
+ {
+ get
+ {
+ if (m_EscapeBuilder == null)
+ m_EscapeBuilder = new StringBuilder();
+ return m_EscapeBuilder;
+ }
+ }
+ internal static string Escape(string aText)
+ {
+ var sb = EscapeBuilder;
+ sb.Length = 0;
+ if (sb.Capacity < aText.Length + aText.Length / 10)
+ sb.Capacity = aText.Length + aText.Length / 10;
+ foreach (char c in aText)
+ {
+ switch (c)
+ {
+ case '\\':
+ sb.Append("\\\\");
+ break;
+ case '\"':
+ sb.Append("\\\"");
+ break;
+ case '\n':
+ sb.Append("\\n");
+ break;
+ case '\r':
+ sb.Append("\\r");
+ break;
+ case '\t':
+ sb.Append("\\t");
+ break;
+ case '\b':
+ sb.Append("\\b");
+ break;
+ case '\f':
+ sb.Append("\\f");
+ break;
+ default:
+ if (c < ' ' || (forceASCII && c > 127))
+ {
+ ushort val = c;
+ sb.Append("\\u").Append(val.ToString("X4"));
+ }
+ else
+ sb.Append(c);
+ break;
+ }
+ }
+ string result = sb.ToString();
+ sb.Length = 0;
+ return result;
+ }
+
+ private static JSONNode ParseElement(string token, bool quoted)
+ {
+ if (quoted)
+ return token;
+ string tmp = token.ToLower();
+ if (tmp == "false" || tmp == "true")
+ return tmp == "true";
+ if (tmp == "null")
+ return JSONNull.CreateOrGet();
+ double val;
+ if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out val))
+ return val;
+ else
+ return token;
+ }
+
+ public static JSONNode Parse(string aJSON)
+ {
+ Stack stack = new Stack();
+ JSONNode ctx = null;
+ int i = 0;
+ StringBuilder Token = new StringBuilder();
+ string TokenName = "";
+ bool QuoteMode = false;
+ bool TokenIsQuoted = false;
+ while (i < aJSON.Length)
+ {
+ switch (aJSON[i])
+ {
+ case '{':
+ if (QuoteMode)
+ {
+ Token.Append(aJSON[i]);
+ break;
+ }
+ stack.Push(new JSONObject());
+ if (ctx != null)
+ {
+ ctx.Add(TokenName, stack.Peek());
+ }
+ TokenName = "";
+ Token.Length = 0;
+ ctx = stack.Peek();
+ break;
+
+ case '[':
+ if (QuoteMode)
+ {
+ Token.Append(aJSON[i]);
+ break;
+ }
+
+ stack.Push(new JSONArray());
+ if (ctx != null)
+ {
+ ctx.Add(TokenName, stack.Peek());
+ }
+ TokenName = "";
+ Token.Length = 0;
+ ctx = stack.Peek();
+ break;
+
+ case '}':
+ case ']':
+ if (QuoteMode)
+ {
+
+ Token.Append(aJSON[i]);
+ break;
+ }
+ if (stack.Count == 0)
+ throw new Exception("JSON Parse: Too many closing brackets");
+
+ stack.Pop();
+ if (Token.Length > 0 || TokenIsQuoted)
+ ctx.Add(TokenName, ParseElement(Token.ToString(), TokenIsQuoted));
+ TokenIsQuoted = false;
+ TokenName = "";
+ Token.Length = 0;
+ if (stack.Count > 0)
+ ctx = stack.Peek();
+ break;
+
+ case ':':
+ if (QuoteMode)
+ {
+ Token.Append(aJSON[i]);
+ break;
+ }
+ TokenName = Token.ToString();
+ Token.Length = 0;
+ TokenIsQuoted = false;
+ break;
+
+ case '"':
+ QuoteMode ^= true;
+ TokenIsQuoted |= QuoteMode;
+ break;
+
+ case ',':
+ if (QuoteMode)
+ {
+ Token.Append(aJSON[i]);
+ break;
+ }
+ if (Token.Length > 0 || TokenIsQuoted)
+ ctx.Add(TokenName, ParseElement(Token.ToString(), TokenIsQuoted));
+ TokenIsQuoted = false;
+ TokenName = "";
+ Token.Length = 0;
+ TokenIsQuoted = false;
+ break;
+
+ case '\r':
+ case '\n':
+ break;
+
+ case ' ':
+ case '\t':
+ if (QuoteMode)
+ Token.Append(aJSON[i]);
+ break;
+
+ case '\\':
+ ++i;
+ if (QuoteMode)
+ {
+ char C = aJSON[i];
+ switch (C)
+ {
+ case 't':
+ Token.Append('\t');
+ break;
+ case 'r':
+ Token.Append('\r');
+ break;
+ case 'n':
+ Token.Append('\n');
+ break;
+ case 'b':
+ Token.Append('\b');
+ break;
+ case 'f':
+ Token.Append('\f');
+ break;
+ case 'u':
+ {
+ string s = aJSON.Substring(i + 1, 4);
+ Token.Append((char)int.Parse(
+ s,
+ System.Globalization.NumberStyles.AllowHexSpecifier));
+ i += 4;
+ break;
+ }
+ default:
+ Token.Append(C);
+ break;
+ }
+ }
+ break;
+ case '/':
+ if (allowLineComments && !QuoteMode && i + 1 < aJSON.Length && aJSON[i + 1] == '/')
+ {
+ while (++i < aJSON.Length && aJSON[i] != '\n' && aJSON[i] != '\r') ;
+ break;
+ }
+ Token.Append(aJSON[i]);
+ break;
+ case '\uFEFF': // remove / ignore BOM (Byte Order Mark)
+ break;
+
+ default:
+ Token.Append(aJSON[i]);
+ break;
+ }
+ ++i;
+ }
+ if (QuoteMode)
+ {
+ throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
+ }
+ if (ctx == null)
+ return ParseElement(Token.ToString(), TokenIsQuoted);
+ return ctx;
+ }
+
+ }
+ // End of JSONNode
+
+ public partial class JSONArray : JSONNode
+ {
+ private List m_List = new List();
+ private bool inline = false;
+ public override bool Inline
+ {
+ get { return inline; }
+ set { inline = value; }
+ }
+
+ public override JSONNodeType Tag { get { return JSONNodeType.Array; } }
+ public override bool IsArray { get { return true; } }
+ public override Enumerator GetEnumerator() { return new Enumerator(m_List.GetEnumerator()); }
+
+ public override JSONNode this[int aIndex]
+ {
+ get
+ {
+ if (aIndex < 0 || aIndex >= m_List.Count)
+ return new JSONLazyCreator(this);
+ return m_List[aIndex];
+ }
+ set
+ {
+ if (value == null)
+ value = JSONNull.CreateOrGet();
+ if (aIndex < 0 || aIndex >= m_List.Count)
+ m_List.Add(value);
+ else
+ m_List[aIndex] = value;
+ }
+ }
+
+ public override JSONNode this[string aKey]
+ {
+ get { return new JSONLazyCreator(this); }
+ set
+ {
+ if (value == null)
+ value = JSONNull.CreateOrGet();
+ m_List.Add(value);
+ }
+ }
+
+ public override int Count
+ {
+ get { return m_List.Count; }
+ }
+
+ public override void Add(string aKey, JSONNode aItem)
+ {
+ if (aItem == null)
+ aItem = JSONNull.CreateOrGet();
+ m_List.Add(aItem);
+ }
+
+ public override JSONNode Remove(int aIndex)
+ {
+ if (aIndex < 0 || aIndex >= m_List.Count)
+ return null;
+ JSONNode tmp = m_List[aIndex];
+ m_List.RemoveAt(aIndex);
+ return tmp;
+ }
+
+ public override JSONNode Remove(JSONNode aNode)
+ {
+ m_List.Remove(aNode);
+ return aNode;
+ }
+
+ public override JSONNode Clone()
+ {
+ var node = new JSONArray();
+ node.m_List.Capacity = m_List.Capacity;
+ foreach (var n in m_List)
+ {
+ if (n != null)
+ node.Add(n.Clone());
+ else
+ node.Add(null);
+ }
+ return node;
+ }
+
+ public override IEnumerable Children
+ {
+ get
+ {
+ foreach (JSONNode N in m_List)
+ yield return N;
+ }
+ }
+
+
+ internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
+ {
+ aSB.Append('[');
+ int count = m_List.Count;
+ if (inline)
+ aMode = JSONTextMode.Compact;
+ for (int i = 0; i < count; i++)
+ {
+ if (i > 0)
+ aSB.Append(',');
+ if (aMode == JSONTextMode.Indent)
+ aSB.AppendLine();
+
+ if (aMode == JSONTextMode.Indent)
+ aSB.Append(' ', aIndent + aIndentInc);
+ m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
+ }
+ if (aMode == JSONTextMode.Indent)
+ aSB.AppendLine().Append(' ', aIndent);
+ aSB.Append(']');
+ }
+ }
+ // End of JSONArray
+
+ public partial class JSONObject : JSONNode
+ {
+ private Dictionary m_Dict = new Dictionary();
+
+ private bool inline = false;
+ public override bool Inline
+ {
+ get { return inline; }
+ set { inline = value; }
+ }
+
+ public override JSONNodeType Tag { get { return JSONNodeType.Object; } }
+ public override bool IsObject { get { return true; } }
+
+ public override Enumerator GetEnumerator() { return new Enumerator(m_Dict.GetEnumerator()); }
+
+
+ public override JSONNode this[string aKey]
+ {
+ get
+ {
+ if (m_Dict.ContainsKey(aKey))
+ return m_Dict[aKey];
+ else
+ return new JSONLazyCreator(this, aKey);
+ }
+ set
+ {
+ if (value == null)
+ value = JSONNull.CreateOrGet();
+ if (m_Dict.ContainsKey(aKey))
+ m_Dict[aKey] = value;
+ else
+ m_Dict.Add(aKey, value);
+ }
+ }
+
+ public override JSONNode this[int aIndex]
+ {
+ get
+ {
+ if (aIndex < 0 || aIndex >= m_Dict.Count)
+ return null;
+ return m_Dict.ElementAt(aIndex).Value;
+ }
+ set
+ {
+ if (value == null)
+ value = JSONNull.CreateOrGet();
+ if (aIndex < 0 || aIndex >= m_Dict.Count)
+ return;
+ string key = m_Dict.ElementAt(aIndex).Key;
+ m_Dict[key] = value;
+ }
+ }
+
+ public override int Count
+ {
+ get { return m_Dict.Count; }
+ }
+
+ public override void Add(string aKey, JSONNode aItem)
+ {
+ if (aItem == null)
+ aItem = JSONNull.CreateOrGet();
+
+ if (aKey != null)
+ {
+ if (m_Dict.ContainsKey(aKey))
+ m_Dict[aKey] = aItem;
+ else
+ m_Dict.Add(aKey, aItem);
+ }
+ else
+ m_Dict.Add(Guid.NewGuid().ToString(), aItem);
+ }
+
+ public override JSONNode Remove(string aKey)
+ {
+ if (!m_Dict.ContainsKey(aKey))
+ return null;
+ JSONNode tmp = m_Dict[aKey];
+ m_Dict.Remove(aKey);
+ return tmp;
+ }
+
+ public override JSONNode Remove(int aIndex)
+ {
+ if (aIndex < 0 || aIndex >= m_Dict.Count)
+ return null;
+ var item = m_Dict.ElementAt(aIndex);
+ m_Dict.Remove(item.Key);
+ return item.Value;
+ }
+
+ public override JSONNode Remove(JSONNode aNode)
+ {
+ try
+ {
+ var item = m_Dict.Where(k => k.Value == aNode).First();
+ m_Dict.Remove(item.Key);
+ return aNode;
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ public override JSONNode Clone()
+ {
+ var node = new JSONObject();
+ foreach (var n in m_Dict)
+ {
+ node.Add(n.Key, n.Value.Clone());
+ }
+ return node;
+ }
+
+ public override bool HasKey(string aKey)
+ {
+ return m_Dict.ContainsKey(aKey);
+ }
+
+ public override JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
+ {
+ JSONNode res;
+ if (m_Dict.TryGetValue(aKey, out res))
+ return res;
+ return aDefault;
+ }
+
+ public override IEnumerable Children
+ {
+ get
+ {
+ foreach (KeyValuePair N in m_Dict)
+ yield return N.Value;
+ }
+ }
+
+ internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
+ {
+ aSB.Append('{');
+ bool first = true;
+ if (inline)
+ aMode = JSONTextMode.Compact;
+ foreach (var k in m_Dict)
+ {
+ if (!first)
+ aSB.Append(',');
+ first = false;
+ if (aMode == JSONTextMode.Indent)
+ aSB.AppendLine();
+ if (aMode == JSONTextMode.Indent)
+ aSB.Append(' ', aIndent + aIndentInc);
+ aSB.Append('\"').Append(Escape(k.Key)).Append('\"');
+ if (aMode == JSONTextMode.Compact)
+ aSB.Append(':');
+ else
+ aSB.Append(" : ");
+ k.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
+ }
+ if (aMode == JSONTextMode.Indent)
+ aSB.AppendLine().Append(' ', aIndent);
+ aSB.Append('}');
+ }
+
+ }
+ // End of JSONObject
+
+ public partial class JSONString : JSONNode
+ {
+ private string m_Data;
+
+ public override JSONNodeType Tag { get { return JSONNodeType.String; } }
+ public override bool IsString { get { return true; } }
+
+ public override Enumerator GetEnumerator() { return new Enumerator(); }
+
+
+ public override string Value
+ {
+ get { return m_Data; }
+ set
+ {
+ m_Data = value;
+ }
+ }
+
+ public JSONString(string aData)
+ {
+ m_Data = aData;
+ }
+ public override JSONNode Clone()
+ {
+ return new JSONString(m_Data);
+ }
+
+ internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
+ {
+ aSB.Append('\"').Append(Escape(m_Data)).Append('\"');
+ }
+ public override bool Equals(object obj)
+ {
+ if (base.Equals(obj))
+ return true;
+ string s = obj as string;
+ if (s != null)
+ return m_Data == s;
+ JSONString s2 = obj as JSONString;
+ if (s2 != null)
+ return m_Data == s2.m_Data;
+ return false;
+ }
+ public override int GetHashCode()
+ {
+ return m_Data.GetHashCode();
+ }
+ }
+ // End of JSONString
+
+ public partial class JSONNumber : JSONNode
+ {
+ private double m_Data;
+
+ public override JSONNodeType Tag { get { return JSONNodeType.Number; } }
+ public override bool IsNumber { get { return true; } }
+ public override Enumerator GetEnumerator() { return new Enumerator(); }
+
+ public override string Value
+ {
+ get { return m_Data.ToString(CultureInfo.InvariantCulture); }
+ set
+ {
+ double v;
+ if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out v))
+ m_Data = v;
+ }
+ }
+
+ public override double AsDouble
+ {
+ get { return m_Data; }
+ set { m_Data = value; }
+ }
+ public override long AsLong
+ {
+ get { return (long)m_Data; }
+ set { m_Data = value; }
+ }
+
+ public JSONNumber(double aData)
+ {
+ m_Data = aData;
+ }
+
+ public JSONNumber(string aData)
+ {
+ Value = aData;
+ }
+
+ public override JSONNode Clone()
+ {
+ return new JSONNumber(m_Data);
+ }
+
+ internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
+ {
+ aSB.Append(Value);
+ }
+ private static bool IsNumeric(object value)
+ {
+ return value is int || value is uint
+ || value is float || value is double
+ || value is decimal
+ || value is long || value is ulong
+ || value is short || value is ushort
+ || value is sbyte || value is byte;
+ }
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ return false;
+ if (base.Equals(obj))
+ return true;
+ JSONNumber s2 = obj as JSONNumber;
+ if (s2 != null)
+ return m_Data == s2.m_Data;
+ if (IsNumeric(obj))
+ return Convert.ToDouble(obj) == m_Data;
+ return false;
+ }
+ public override int GetHashCode()
+ {
+ return m_Data.GetHashCode();
+ }
+ }
+ // End of JSONNumber
+
+ public partial class JSONBool : JSONNode
+ {
+ private bool m_Data;
+
+ public override JSONNodeType Tag { get { return JSONNodeType.Boolean; } }
+ public override bool IsBoolean { get { return true; } }
+ public override Enumerator GetEnumerator() { return new Enumerator(); }
+
+ public override string Value
+ {
+ get { return m_Data.ToString(); }
+ set
+ {
+ bool v;
+ if (bool.TryParse(value, out v))
+ m_Data = v;
+ }
+ }
+ public override bool AsBool
+ {
+ get { return m_Data; }
+ set { m_Data = value; }
+ }
+
+ public JSONBool(bool aData)
+ {
+ m_Data = aData;
+ }
+
+ public JSONBool(string aData)
+ {
+ Value = aData;
+ }
+
+ public override JSONNode Clone()
+ {
+ return new JSONBool(m_Data);
+ }
+
+ internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
+ {
+ aSB.Append((m_Data) ? "true" : "false");
+ }
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ return false;
+ if (obj is bool)
+ return m_Data == (bool)obj;
+ return false;
+ }
+ public override int GetHashCode()
+ {
+ return m_Data.GetHashCode();
+ }
+ }
+ // End of JSONBool
+
+ public partial class JSONNull : JSONNode
+ {
+ static JSONNull m_StaticInstance = new JSONNull();
+ public static bool reuseSameInstance = true;
+ public static JSONNull CreateOrGet()
+ {
+ if (reuseSameInstance)
+ return m_StaticInstance;
+ return new JSONNull();
+ }
+ private JSONNull() { }
+
+ public override JSONNodeType Tag { get { return JSONNodeType.NullValue; } }
+ public override bool IsNull { get { return true; } }
+ public override Enumerator GetEnumerator() { return new Enumerator(); }
+
+ public override string Value
+ {
+ get { return "null"; }
+ set { }
+ }
+ public override bool AsBool
+ {
+ get { return false; }
+ set { }
+ }
+
+ public override JSONNode Clone()
+ {
+ return CreateOrGet();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (object.ReferenceEquals(this, obj))
+ return true;
+ return (obj is JSONNull);
+ }
+ public override int GetHashCode()
+ {
+ return 0;
+ }
+
+ internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
+ {
+ aSB.Append("null");
+ }
+ }
+ // End of JSONNull
+
+ internal partial class JSONLazyCreator : JSONNode
+ {
+ private JSONNode m_Node = null;
+ private string m_Key = null;
+ public override JSONNodeType Tag { get { return JSONNodeType.None; } }
+ public override Enumerator GetEnumerator() { return new Enumerator(); }
+
+ public JSONLazyCreator(JSONNode aNode)
+ {
+ m_Node = aNode;
+ m_Key = null;
+ }
+
+ public JSONLazyCreator(JSONNode aNode, string aKey)
+ {
+ m_Node = aNode;
+ m_Key = aKey;
+ }
+
+ private T Set(T aVal) where T : JSONNode
+ {
+ if (m_Key == null)
+ m_Node.Add(aVal);
+ else
+ m_Node.Add(m_Key, aVal);
+ m_Node = null; // Be GC friendly.
+ return aVal;
+ }
+
+ public override JSONNode this[int aIndex]
+ {
+ get { return new JSONLazyCreator(this); }
+ set { Set(new JSONArray()).Add(value); }
+ }
+
+ public override JSONNode this[string aKey]
+ {
+ get { return new JSONLazyCreator(this, aKey); }
+ set { Set(new JSONObject()).Add(aKey, value); }
+ }
+
+ public override void Add(JSONNode aItem)
+ {
+ Set(new JSONArray()).Add(aItem);
+ }
+
+ public override void Add(string aKey, JSONNode aItem)
+ {
+ Set(new JSONObject()).Add(aKey, aItem);
+ }
+
+ public static bool operator ==(JSONLazyCreator a, object b)
+ {
+ if (b == null)
+ return true;
+ return System.Object.ReferenceEquals(a, b);
+ }
+
+ public static bool operator !=(JSONLazyCreator a, object b)
+ {
+ return !(a == b);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ return true;
+ return System.Object.ReferenceEquals(this, obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return 0;
+ }
+
+ public override int AsInt
+ {
+ get { Set(new JSONNumber(0)); return 0; }
+ set { Set(new JSONNumber(value)); }
+ }
+
+ public override float AsFloat
+ {
+ get { Set(new JSONNumber(0.0f)); return 0.0f; }
+ set { Set(new JSONNumber(value)); }
+ }
+
+ public override double AsDouble
+ {
+ get { Set(new JSONNumber(0.0)); return 0.0; }
+ set { Set(new JSONNumber(value)); }
+ }
+
+ public override long AsLong
+ {
+ get
+ {
+ if (longAsString)
+ Set(new JSONString("0"));
+ else
+ Set(new JSONNumber(0.0));
+ return 0L;
+ }
+ set
+ {
+ if (longAsString)
+ Set(new JSONString(value.ToString()));
+ else
+ Set(new JSONNumber(value));
+ }
+ }
+
+ public override bool AsBool
+ {
+ get { Set(new JSONBool(false)); return false; }
+ set { Set(new JSONBool(value)); }
+ }
+
+ public override JSONArray AsArray
+ {
+ get { return Set(new JSONArray()); }
+ }
+
+ public override JSONObject AsObject
+ {
+ get { return Set(new JSONObject()); }
+ }
+ internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
+ {
+ aSB.Append("null");
+ }
+ }
+ // End of JSONLazyCreator
+
+ public static class JSON
+ {
+ public static JSONNode Parse(string aJSON)
+ {
+ return JSONNode.Parse(aJSON);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRSimpleJSON.cs.meta b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRSimpleJSON.cs.meta
new file mode 100644
index 0000000..7ef1d6a
--- /dev/null
+++ b/Assets/SteamVR/OpenVRUnityXRPackage/Editor/OpenVRSimpleJSON.cs.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: ca02308d9febaa442a742ecaaaa06d2c
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: