From 7030a4ddf4846db6efd184fdba63d3c04272a911 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 2 Jun 2022 17:56:36 +0900 Subject: [PATCH] =?UTF-8?q?VRMShaders.PathObject=20=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=82=20MigrationMenu=20=E3=81=A7=E4=BD=BF?= =?UTF-8?q?=E3=81=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UniGLTF/Runtime/UniGLTF/IO/UnityPath.cs | 4 +- Assets/VRM10/Editor/MigrationMenu.cs | 37 ++-- .../VRMShaders/GLTF/IO/Editor/PathObject.cs | 171 ++++++++++++++++++ .../GLTF/IO/Editor/PathObject.cs.meta | 11 ++ Assets/VRMShaders/VRM/IO/Runtime/VRM.meta | 8 - 5 files changed, 206 insertions(+), 25 deletions(-) create mode 100644 Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs.meta delete mode 100644 Assets/VRMShaders/VRM/IO/Runtime/VRM.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/UnityPath.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/UnityPath.cs index ff74aeedf..5e3d312c6 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/UnityPath.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/UnityPath.cs @@ -343,8 +343,8 @@ namespace UniGLTF } public static UnityPath FromAsset(UnityEngine.Object asset) - { - var assetPath = AssetDatabase.GetAssetPath(asset); + { + var assetPath = AssetDatabase.GetAssetPath(asset); if (string.IsNullOrEmpty(assetPath)) { throw new System.ArgumentNullException(); diff --git a/Assets/VRM10/Editor/MigrationMenu.cs b/Assets/VRM10/Editor/MigrationMenu.cs index 39c62b578..d62cb76d8 100644 --- a/Assets/VRM10/Editor/MigrationMenu.cs +++ b/Assets/VRM10/Editor/MigrationMenu.cs @@ -6,14 +6,18 @@ namespace UniVRM10 { public static class MigrationMenu { - static string s_lastPath = Application.dataPath; + static VRMShaders.PathObject s_lastPath = VRMShaders.PathObject.UnityAssets; const string CONTEXT_MENU = "Assets/Migration: Vrm1"; [MenuItem(CONTEXT_MENU, true)] static bool Enable() { - var path = UniGLTF.UnityPath.FromAsset(Selection.activeObject); + if (Selection.activeObject == null) + { + return false; + } + var path = VRMShaders.PathObject.FromAsset(Selection.activeObject); var isVrm = path.Extension.ToLower() == ".vrm"; return isVrm; } @@ -21,27 +25,30 @@ namespace UniVRM10 [MenuItem(CONTEXT_MENU, false)] static void Exec() { - var path = UniGLTF.UnityPath.FromAsset(Selection.activeObject); - var isVrm = path.Extension.ToLower() == ".vrm"; + var path = VRMShaders.PathObject.FromAsset(Selection.activeObject); - var vrm1Bytes = MigrationVrm.Migrate(File.ReadAllBytes(path.FullPath)); + // migrate + var vrm1Bytes = MigrationVrm.Migrate(path.ReadAllBytes()); - var dst = EditorUtility.SaveFilePanel( - "Save vrm1 file", - s_lastPath, - $"{path.FileNameWithoutExtension}_vrm1", - "vrm"); - if (string.IsNullOrEmpty(dst)) + if (!s_lastPath.TrySaveDialog("Save vrm1 file", $"{path.Stem}_vrm1", out VRMShaders.PathObject dst)) { return; } - s_lastPath = Path.GetDirectoryName(dst); + s_lastPath = dst.Parent; // write result - File.WriteAllBytes(dst, vrm1Bytes); + dst.WriteAllBytes(vrm1Bytes); - // immediately import for GUI update - UniGLTF.UnityPath.FromFullpath(dst).ImportAsset(); + if (dst.IsUnderAsset) + { + // immediately import for GUI update + Debug.Log($"import: {dst}"); + dst.ImportAsset(); + } + else + { + Debug.Log($"write: {dst}"); + } } } } diff --git a/Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs b/Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs new file mode 100644 index 000000000..51a53f800 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs @@ -0,0 +1,171 @@ +using System; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace VRMShaders +{ + /// + /// UniGLTF.UnityPath (Assets の ひとつ上がルート) をすべてのパスが扱えるように拡張するのが趣旨。 + /// readonly struct で Immutable であるという主張。 + /// + public readonly struct PathObject + { + /// + /// * Delemeter は / を保証 + /// * .. を解決済み + /// * フルパス + /// + readonly string _FullPath; + + public string FullPath => _FullPath; + + public string Extension => Path.GetExtension(_FullPath); + + public string Stem => Path.GetFileNameWithoutExtension(_FullPath); + + public PathObject Parent => FromFullPath(Path.GetDirectoryName(_FullPath)); + + public bool IsUnderAsset + { + get + { + var assets = UnityAssets; + return _FullPath.StartsWith(assets.FullPath); + } + } + + /// + /// relative from UnityEngine.Application.dataPath + /// + /// + public string UnityPath + { + get + { + var root = UnityRoot; + if (!_FullPath.StartsWith(root.FullPath)) + { + throw new ArgumentException($"{_FullPath} is not under UnityPath"); + } + return _FullPath.Substring(root.FullPath.Length); + } + } + + static PathObject? _root; + public static PathObject UnityRoot + { + get + { + if (!_root.HasValue) + { + _root = FromFullPath(Path.GetDirectoryName(Application.dataPath) + "/"); + } + return _root.Value; + } + } + + public static PathObject UnityAssets => UnityRoot.Child("Assets/"); + + PathObject(string src) + { + if (string.IsNullOrEmpty(src)) + { + throw new ArgumentNullException(); + } + src = src.Replace('\\', '/'); + if (src[0] == '/') + { + _FullPath = src; + } + else + { + if (src.Length >= 3 && src[1] == ':' && src[2] == '/') + { + _FullPath = src; + } + else + { + throw new ArgumentException($"{src} is not fullpath"); + } + } + } + + public override string ToString() + { + try + { + var unityPath = UnityPath; + return $""; + } + catch (ArgumentException) + { + return $""; + } + } + + /// start with "X:/" on Windows else "/" + /// + public static PathObject FromFullPath(string src) + { + return new PathObject(src); + } + + /// relative from UnityEngine.Application.dataPath + /// + public static PathObject FromUnityPath(string src) + { + return UnityRoot.Child(src); + } + + public static PathObject FromAsset(UnityEngine.Object src) + { + if (src == null) + { + throw new ArgumentNullException(); + } + var assetPath = AssetDatabase.GetAssetPath(src); + if (string.IsNullOrEmpty(assetPath)) + { + throw new ArgumentException($"{src} is not asset"); + } + return FromUnityPath(assetPath); + } + + public PathObject Child(string child) + { + return FromFullPath(Path.Combine(_FullPath, child)); + } + + public byte[] ReadAllBytes() + { + return File.ReadAllBytes(_FullPath); + } + + public void WriteAllBytes(byte[] data) + { + File.WriteAllBytes(_FullPath, data); + } + + public void ImportAsset() + { + AssetDatabase.ImportAsset(UnityPath); + } + + public bool TrySaveDialog(string title, string name, out PathObject dst) + { + var path = EditorUtility.SaveFilePanel( + title, + _FullPath, + name, + "vrm"); + if (string.IsNullOrEmpty(path)) + { + dst = default; + return false; + } + dst = PathObject.FromFullPath(path); + return true; + } + } +} diff --git a/Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs.meta b/Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs.meta new file mode 100644 index 000000000..0c5fa088f --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Editor/PathObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d16607c9cf9d05e46b5beec82002d4ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRMShaders/VRM/IO/Runtime/VRM.meta b/Assets/VRMShaders/VRM/IO/Runtime/VRM.meta deleted file mode 100644 index 6d0ee19da..000000000 --- a/Assets/VRMShaders/VRM/IO/Runtime/VRM.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: eb31f565eeca6164694b06ccfe3bc251 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: