diff --git a/Assets/MeshUtility/Editor/AssetsPath.cs b/Assets/MeshUtility/Editor/AssetsPath.cs
new file mode 100644
index 000000000..96f575f20
--- /dev/null
+++ b/Assets/MeshUtility/Editor/AssetsPath.cs
@@ -0,0 +1,309 @@
+using System;
+using System.IO;
+using UnityEngine;
+using System.Collections.Generic;
+using UnityEditor;
+
+
+namespace MeshUtility
+{
+ ///
+ /// Application.dataPath を root とするファイルパスを扱う。
+ /// (Project/Assets)
+ ///
+ public struct AssetsPath
+ {
+ public string RelativePath
+ {
+ get;
+ private set;
+ }
+
+ public override string ToString()
+ {
+ return $"assets://{RelativePath}";
+ }
+
+ public string FileName
+ {
+ get { return Path.GetFileName(RelativePath); }
+ }
+
+ public string FileNameWithoutExtension
+ {
+ get
+ {
+ return Path.GetFileNameWithoutExtension(RelativePath);
+ }
+ }
+
+ public string Extension
+ {
+ get { return Path.GetExtension(RelativePath); }
+ }
+
+ public AssetsPath Parent
+ {
+ get
+ {
+ return new AssetsPath(Path.GetDirectoryName(RelativePath));
+ }
+ }
+
+ static readonly char[] EscapeChars = new char[]
+ {
+ '\\',
+ '/',
+ ':',
+ '*',
+ '?',
+ '"',
+ '<',
+ '>',
+ '|',
+ };
+
+ static string EscapeFilePath(string path)
+ {
+ foreach (var x in EscapeChars)
+ {
+ path = path.Replace(x, '+');
+ }
+ return path;
+ }
+
+ public AssetsPath Child(string name)
+ {
+ if (RelativePath == null)
+ {
+ throw new NotImplementedException();
+ }
+ else if (RelativePath == "")
+ {
+ return new AssetsPath(name);
+ }
+ else
+ {
+ return new AssetsPath(RelativePath + "/" + name);
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ if (RelativePath == null)
+ {
+ return 0;
+ }
+ return RelativePath.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is AssetsPath)
+ {
+ var rhs = (AssetsPath)obj;
+ if (RelativePath == null && rhs.RelativePath == null)
+ {
+ return true;
+ }
+ else if (RelativePath == null)
+ {
+ return false;
+ }
+ else if (rhs.RelativePath == null)
+ {
+ return false;
+ }
+ else
+ {
+ return RelativePath == rhs.RelativePath;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ AssetsPath(string value) : this()
+ {
+ RelativePath = value.Replace("\\", "/");
+ }
+
+ #region FullPath
+ static string s_basePath;
+ static string BaseFullPath
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(s_basePath))
+ {
+ s_basePath = Path.GetFullPath(Application.dataPath).Replace("\\", "/");
+ }
+ return s_basePath;
+ }
+ }
+
+ public string FullPath
+ {
+ get
+ {
+ if (RelativePath == null)
+ {
+ throw new NotImplementedException();
+ }
+ return Path.Combine(BaseFullPath, RelativePath).Replace("\\", "/");
+ }
+ }
+
+ public bool IsFileExists
+ {
+ get { return File.Exists(FullPath); }
+ }
+
+ public bool IsDirectoryExists
+ {
+ get { return Directory.Exists(FullPath); }
+ }
+
+ ///
+ ///
+ ///
+ /// C:/path/to/file
+ ///
+ public static AssetsPath FromFullpath(string fullPath)
+ {
+ if (fullPath == null)
+ {
+ fullPath = "";
+ }
+ fullPath = fullPath.Replace("\\", "/");
+
+ if (fullPath == BaseFullPath)
+ {
+ return new AssetsPath
+ {
+ RelativePath = ""
+ };
+ }
+ else if (fullPath.StartsWith(BaseFullPath + "/"))
+ {
+ return new AssetsPath(fullPath.Substring(BaseFullPath.Length + 1));
+ }
+ else
+ {
+ return default(AssetsPath);
+ }
+ }
+ #endregion
+
+ public IEnumerable TraverseDir()
+ {
+ if (IsDirectoryExists)
+ {
+ yield return this;
+
+ foreach (var child in ChildDirs)
+ {
+ foreach (var x in child.TraverseDir())
+ {
+ yield return x;
+ }
+ }
+ }
+ }
+
+ public IEnumerable ChildDirs
+ {
+ get
+ {
+ foreach (var x in Directory.GetDirectories(FullPath))
+ {
+ yield return AssetsPath.FromFullpath(x);
+ }
+ }
+ }
+
+ public IEnumerable ChildFiles
+ {
+ get
+ {
+ foreach (var x in Directory.GetFiles(FullPath))
+ {
+ yield return AssetsPath.FromFullpath(x);
+ }
+ }
+ }
+
+#if UNITY_EDITOR
+ string UnityPath => $"Assets/{RelativePath}";
+
+ public T GetImporter() where T : AssetImporter
+ {
+ return AssetImporter.GetAtPath(UnityPath) as T;
+ }
+
+ public static AssetsPath FromAsset(UnityEngine.Object asset)
+ {
+ // skip Assets/
+ return new AssetsPath(AssetDatabase.GetAssetPath(asset).Substring(7));
+ }
+
+ public void ImportAsset()
+ {
+ AssetDatabase.ImportAsset(UnityPath);
+ }
+
+ public void EnsureFolder()
+ {
+ if (RelativePath == null)
+ {
+ throw new NotImplementedException();
+ }
+
+ if (!string.IsNullOrEmpty(Parent.RelativePath))
+ {
+ Parent.EnsureFolder();
+ }
+
+ if (!IsDirectoryExists)
+ {
+ var parent = Parent;
+ // ensure parent
+ parent.ImportAsset();
+ // create
+ AssetDatabase.CreateFolder(
+ parent.UnityPath,
+ Path.GetFileName(RelativePath)
+ );
+ ImportAsset();
+ }
+ }
+
+ public UnityEngine.Object[] GetSubAssets()
+ {
+ return AssetDatabase.LoadAllAssetsAtPath(UnityPath);
+ }
+
+ public void CreateAsset(UnityEngine.Object o)
+ {
+ AssetDatabase.CreateAsset(o, UnityPath);
+ }
+
+ public void AddObjectToAsset(UnityEngine.Object o)
+ {
+ AssetDatabase.AddObjectToAsset(o, UnityPath);
+ }
+
+ public T LoadAsset() where T : UnityEngine.Object
+ {
+ return AssetDatabase.LoadAssetAtPath(UnityPath);
+ }
+
+ public AssetsPath GenerateUniqueAssetPath()
+ {
+ return new AssetsPath(AssetDatabase.GenerateUniqueAssetPath(UnityPath));
+ }
+#endif
+ }
+}
diff --git a/Assets/MeshUtility/Editor/AssetsPath.cs.meta b/Assets/MeshUtility/Editor/AssetsPath.cs.meta
new file mode 100644
index 000000000..4918b11e4
--- /dev/null
+++ b/Assets/MeshUtility/Editor/AssetsPath.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: da24ccbbed21eb94d902d42337df3699
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/MeshUtility/Editor/TextureSaver.cs b/Assets/MeshUtility/Editor/TextureSaver.cs
index cffbd39f0..e2425f1d6 100644
--- a/Assets/MeshUtility/Editor/TextureSaver.cs
+++ b/Assets/MeshUtility/Editor/TextureSaver.cs
@@ -7,6 +7,7 @@ namespace MeshUtility
public static class EditorChangeTextureType
{
[MenuItem("Assets/SaveAsPng", true)]
+ [MenuItem("Assets/SaveAsPngLinear", true)]
static bool IsTextureAsset()
{
return Selection.activeObject is Texture2D;
@@ -14,32 +15,52 @@ namespace MeshUtility
[MenuItem("Assets/SaveAsPng")]
static void SaveAsPng()
+ {
+ SaveAsPng(true);
+ }
+
+ [MenuItem("Assets/SaveAsPngLinear")]
+ static void SaveAsPngLinear()
+ {
+ SaveAsPng(false);
+ }
+
+ static void SaveAsPng(bool sRGB)
{
var texture = Selection.activeObject as Texture2D;
- var path = SaveDialog(texture.name);
+ var path = SaveDialog(AssetsPath.FromAsset(texture));
if (string.IsNullOrEmpty(path))
{
return;
}
File.WriteAllBytes(path, texture.EncodeToPNG());
- Debug.Log($"save: ${path}");
+ Debug.Log($"save: {path}");
+
+ var assetsPath = AssetsPath.FromFullpath(path);
+
+ EditorApplication.delayCall += () =>
+ {
+ assetsPath.ImportAsset();
+ var importer = assetsPath.GetImporter();
+ if (importer == null)
+ {
+ Debug.LogWarningFormat("fail to get TextureImporter: {0}", assetsPath);
+ }
+ importer.sRGBTexture = sRGB;
+ importer.SaveAndReimport();
+ Debug.Log($"sRGB: {sRGB}");
+ };
}
private static string m_lastExportDir;
- static string SaveDialog(string name)
+ static string SaveDialog(AssetsPath assetsPath)
{
- string directory;
- if (string.IsNullOrEmpty(m_lastExportDir))
- directory = Directory.GetParent(Application.dataPath).ToString();
- else
- directory = m_lastExportDir;
-
// save dialog
var path = EditorUtility.SaveFilePanel(
"Save png",
- directory,
- $"{name}.png",
+ assetsPath.Parent.FullPath,
+ $"{assetsPath.FileNameWithoutExtension}.png",
"png");
if (!string.IsNullOrEmpty(path))
{