// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using System.IO;
using System.Linq;
using UltimateXR.Core;
using UltimateXR.Core.Components;
using UltimateXR.Extensions.System.IO;
using UnityEditor;
using UnityEditor.Compilation;
using UnityEngine;
namespace UltimateXR.Editor
{
public static partial class UxrEditorUtils
{
#region Public Types & Data
public static readonly string ApplicationProjectPath = Path.GetFullPath(Application.dataPath.Substring(0, Application.dataPath.Length - "Assets".Length));
#if ULTIMATEXR_PACKAGE
public static readonly string RelativeInstallationPath = $"Packages/{UxrConstants.PackageName}/";
public static readonly string FullInstallationPath = $"{Path.GetFullPath(RelativeInstallationPath)}";
public static readonly string InstalledSamplesPath = $"{Application.dataPath}/Samples/{UxrConstants.UltimateXR}/";
#else
public static string RelativeInstallationPath => GetProjectRelativePath(FullInstallationPath);
public static string FullInstallationPath
{
get
{
// If we cached it, return it immediately
if (!string.IsNullOrEmpty(CachedFullInstallationPath))
{
return CachedFullInstallationPath;
}
// Try to infer installation path using a well known source file. This way when UltimateXR is installed
// in the Assets/ folder it can be moved around and doesn't require to be in a fixed installation path.
Assembly assembly = CompilationPipeline.GetAssemblies().FirstOrDefault(a => a.name == UxrConstants.UltimateXR);
if (assembly == null)
{
return DefaultFullInstallationPath;
}
string knownFileName = $"{nameof(UxrComponent)}.cs";
string knownFilePath = assembly.sourceFiles.FirstOrDefault(f => f.EndsWith(knownFileName));
if (string.IsNullOrEmpty(knownFilePath))
{
return DefaultFullInstallationPath;
}
CachedFullInstallationPath = Path.GetFullPath(PathExt.Combine(ApplicationProjectPath, PathExt.Combine(Path.GetDirectoryName(knownFilePath), @"..\..\..")));
return CachedFullInstallationPath;
}
}
#endif
public static string HandPosePresetsPath => PathExt.Combine(FullInstallationPath, "Editor/Manipulation/HandPoses/HandPosePresets");
#endregion
#region Public Methods
///
/// Returns whether an asset can be loaded using
///
/// Path to check
/// Boolean telling whether the given asset can be loaded
public static bool CanLoadUsingAssetDatabase(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
#if ULTIMATEXR_PACKAGE
if (PathExt.IsSubDirectoryOf(path, FullInstallationPath))
{
return true;
}
#endif
return PathExt.IsSubDirectoryOf(path, Application.dataPath);
}
///
/// Returns whether the given path is in the current project.
///
/// Path to check
/// Boolean telling whether the given path is in the current project
public static bool PathIsInCurrentProject(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
return PathExt.IsSubDirectoryOf(path, Application.dataPath);
}
///
/// Returns whether the given path is inside the UltimateXR framework.
///
/// Path to check
/// Boolean telling whether the given path is inside the UltimateXR framework
public static bool PathIsInUltimateXR(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
#if ULTIMATEXR_PACKAGE
if (PathExt.IsSubDirectoryOf(path, InstalledSamplesPath))
{
return true;
}
#endif
return PathExt.IsSubDirectoryOf(path, FullInstallationPath);
}
///
/// Transforms a full path to a path relative to the current project folder.
///
/// Full path
/// Path relative to the current project folder
/// The given path does not belong to the current project.
public static string GetProjectRelativePath(string path)
{
if (!PathExt.IsSubDirectoryOf(path, Application.dataPath))
{
throw new DirectoryNotFoundException($"{nameof(GetProjectRelativePath)}: Path {path} needs to be under current project's Assets folder");
}
return path.Substring(Application.dataPath.Length - "Assets".Length);
}
///
/// Gets a list of the files inside the hand pose presets folder
///
/// Hand pose preset file names
public static string[] GetHandPosePresetFiles()
{
string[] files = Directory.GetFiles(HandPosePresetsPath);
#if ULTIMATEXR_PACKAGE
for (int i = 0; i < files.Length; ++i)
{
files[i] = $"Packages/{UxrConstants.PackageName}/{files[i].Substring(FullInstallationPath.Length)}";
}
#else
for (int i = 0; i < files.Length; ++i)
{
files[i] = $"Assets{files[i].Substring(Application.dataPath.Length)}";
}
#endif
return files;
}
///
/// Transforms a HandPoseAsset file path to a relative path that can be used to load an asset through
/// .
///
/// Path
/// Path compatible with
public static string ToHandPoseAssetPath(string path)
{
#if ULTIMATEXR_PACKAGE
if (PathExt.IsSubDirectoryOf(path, FullInstallationPath))
{
path = $"Packages/{UxrConstants.PackageName}/{path.Substring(FullInstallationPath.Length)}";
}
else
#endif
if (PathExt.IsSubDirectoryOf(path, Application.dataPath))
{
path = $"Assets{path.Substring(Application.dataPath.Length)}";
}
return path;
}
///
/// Opens a folder selection dialog and returns the selected path or if cancelled or the
/// folder was not in the project.
/// If the folder was not in the project it will take care of displaying an error message.
///
/// The path relative to the project folder. It will start with Assets
/// title parameter of
/// folder parameter of
/// defaultName parameter of
/// Whether a valid path was returned/
public static bool OpenFolderPanel(out string relativeProjectPath, string title = "Select folder", string folder = "", string defaultName = "")
{
relativeProjectPath = string.Empty;
string absolutePath = EditorUtility.OpenFolderPanel("Select folder", folder, defaultName);
if (!string.IsNullOrEmpty(absolutePath))
{
try
{
relativeProjectPath = GetProjectRelativePath(absolutePath);
return true;
}
catch (DirectoryNotFoundException)
{
ShowFolderNotInProjectError();
return false;
}
}
return false;
}
#endregion
#region Private Types & Data
#if !ULTIMATEXR_PACKAGE
private static readonly string DefaultFullInstallationPath = $"{Application.dataPath}/{UxrConstants.UltimateXR}/";
private static string CachedFullInstallationPath;
#endif
#endregion
}
}