extract texture from external path to asset path

This commit is contained in:
ousttrue
2021-03-18 14:39:12 +09:00
parent c66beb3424
commit 8d95a4d1eb
5 changed files with 104 additions and 103 deletions

View File

@@ -40,7 +40,7 @@ namespace UniGLTF
{
if (GUILayout.Button("Extract Materials And Textures ..."))
{
ExtractMaterialsAndTextures(importer);
ExtractMaterialsAndTextures(importer, parser);
}
}
@@ -111,7 +111,7 @@ namespace UniGLTF
AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
}
static void ExtractMaterialsAndTextures(ScriptedImporter self)
static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser)
{
if (string.IsNullOrEmpty(self.assetPath))
{
@@ -122,14 +122,16 @@ namespace UniGLTF
{
self.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), externalObject.name), externalObject);
};
Action<IEnumerable<string>> onCompleted = _ =>
Action<IEnumerable<UnityPath>> onCompleted = _ =>
{
AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
self.ExtractMaterials();
AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
};
TextureExtractor.ExtractTextures(self.assetPath,
var assetPath = UnityPath.FromFullpath(parser.TargetPath);
var dirName = $"{assetPath.FileNameWithoutExtension}.Textures";
TextureExtractor.ExtractTextures(parser, assetPath.Parent.Child(dirName),
GltfTextureEnumerator.Enumerate,
self.GetSubAssets<UnityEngine.Texture2D>(self.assetPath).ToArray(),
addRemap,

View File

@@ -17,23 +17,15 @@ namespace UniGLTF
public glTF GLTF => m_parser.GLTF;
public IStorage Storage => m_parser.Storage;
public readonly Dictionary<string, GetTextureParam> Textures = new Dictionary<string, GetTextureParam>();
public readonly Dictionary<UnityPath, GetTextureParam> Textures = new Dictionary<UnityPath, GetTextureParam>();
UnityEngine.Texture2D[] m_subAssets;
string m_path;
UnityPath m_textureDirectory;
public TextureExtractor(string assetPath, UnityEngine.Texture2D[] subAssets)
public TextureExtractor(GltfParser parser, UnityPath textureDirectory, UnityEngine.Texture2D[] subAssets)
{
// parse GLTF
m_parser = new GltfParser();
m_parser.ParsePath(assetPath);
m_path = $"{Path.GetDirectoryName(assetPath)}/{Path.GetFileNameWithoutExtension(assetPath)}.Textures";
SafeCreateDirectory(m_path);
if (assetPath == null)
{
throw new ArgumentNullException();
}
m_parser = parser;
m_textureDirectory = textureDirectory;
m_textureDirectory.EnsureFolder();
m_subAssets = subAssets;
}
@@ -56,14 +48,14 @@ namespace UniGLTF
}
var subAsset = m_subAssets.FirstOrDefault(x => x.name == param.ConvertedName);
string targetPath = "";
UnityPath targetPath = default;
if (hasUri && !param.ExtractConverted)
{
var gltfTexture = GLTF.textures[param.Index0.Value];
var gltfImage = GLTF.images[gltfTexture.source];
var ext = GetExt(gltfImage.mimeType, gltfImage.uri);
targetPath = $"{Path.GetDirectoryName(m_path)}/{param.GltflName}{ext}";
targetPath = m_textureDirectory.Child($"{param.GltflName}{ext}");
}
else
{
@@ -73,9 +65,9 @@ namespace UniGLTF
case GetTextureParam.TextureTypes.StandardMap:
{
// write converted texture
targetPath = $"{m_path}/{param.ConvertedName}.png";
File.WriteAllBytes(targetPath, subAsset.EncodeToPNG().ToArray());
AssetDatabase.ImportAsset(targetPath);
targetPath = m_textureDirectory.Child($"{param.ConvertedName}.png");
File.WriteAllBytes(targetPath.FullPath, subAsset.EncodeToPNG().ToArray());
targetPath.ImportAsset();
break;
}
@@ -85,9 +77,9 @@ namespace UniGLTF
var gltfTexture = GLTF.textures[param.Index0.Value];
var gltfImage = GLTF.images[gltfTexture.source];
var ext = GetExt(gltfImage.mimeType, gltfImage.uri);
targetPath = $"{m_path}/{param.GltflName}{ext}";
File.WriteAllBytes(targetPath, GLTF.GetImageBytes(Storage, gltfTexture.source).ToArray());
AssetDatabase.ImportAsset(targetPath);
targetPath = m_textureDirectory.Child($"{param.GltflName}{ext}");
File.WriteAllBytes(targetPath.FullPath, GLTF.GetImageBytes(Storage, gltfTexture.source).ToArray());
targetPath.ImportAsset();
break;
}
}
@@ -115,11 +107,11 @@ namespace UniGLTF
/// <param name="importer"></param>
/// <param name="dirName"></param>
/// <param name="onCompleted"></param>
public static void ExtractTextures(string assetPath, TextureEnumerator textureEnumerator, Texture2D[] subAssets, Action<Texture2D> addRemap, Action<IEnumerable<string>> onCompleted = null)
public static void ExtractTextures(GltfParser parser, UnityPath textureDirectory,
TextureEnumerator textureEnumerator, Texture2D[] subAssets, Action<Texture2D> addRemap,
Action<IEnumerable<UnityPath>> onCompleted = null)
{
var extractor = new TextureExtractor(assetPath, subAssets);
var normalMaps = new List<string>();
var extractor = new TextureExtractor(parser, textureDirectory, subAssets);
foreach (var x in textureEnumerator(extractor.GLTF))
{
var gltfTexture = extractor.GLTF.textures[x.Index0.Value];
@@ -137,7 +129,7 @@ namespace UniGLTF
var param = kv.Value;
// remap
var externalObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Texture2D>(targetPath);
var externalObject = targetPath.LoadAsset<Texture2D>();
if (externalObject != null)
{
addRemap(externalObject);

View File

@@ -120,8 +120,7 @@ namespace VRM
/// <summary>
/// Extract images from glb or gltf out of Assets folder.
/// </summary>
/// <param name="assetPath"></param>
public void ConvertAndExtractImages(UnityPath assetPath, Action<IEnumerable<string>> onTextureReloaded)
public void ConvertAndExtractImages(Action<IEnumerable<UnityPath>> onTextureReloaded)
{
//
// convert images(metallic roughness, occlusion map)
@@ -150,10 +149,9 @@ namespace VRM
.Where(x => x.IsUsed)
.Select(x => x.Texture)
.ToArray();
var prefabParentDir = assetPath.Parent;
var folder = assetPath.GetAssetFolder(".Textures");
var vrmTextures = new VRMTextureEnumerator(m_context.VRM);
TextureExtractor.ExtractTextures(assetPath.Value, vrmTextures.Enumerate, subAssets, _ => { }, onTextureReloaded);
var dirName = $"{m_prefabPath.FileNameWithoutExtension}.Textures";
TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), vrmTextures.Enumerate, subAssets, _ => { }, onTextureReloaded);
}
bool SaveAsAsset(UnityEngine.Object o)

View File

@@ -21,72 +21,81 @@ namespace VRM
if (Application.isPlaying)
{
// load into scene
var parser = new GltfParser();
parser.ParsePath(path);
using (var context = new VRMImporterContext(parser))
{
context.Load();
context.EnableUpdateWhenOffscreen();
context.ShowMeshes();
context.DisposeOnGameObjectDestroyed();
Selection.activeGameObject = context.Root;
}
ImportRuntime(path);
return;
}
else
if (path.StartsWithUnityAssetPath())
{
if (path.StartsWithUnityAssetPath())
Debug.LogWarningFormat("disallow import from folder under the Assets");
return;
}
var prefabPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab");
if (string.IsNullOrEmpty(path))
{
return;
}
ImportAsset(path, UnityPath.FromFullpath(prefabPath));
}
static void ImportRuntime(string path)
{
// load into scene
var parser = new GltfParser();
parser.ParsePath(path);
using (var context = new VRMImporterContext(parser))
{
context.Load();
context.EnableUpdateWhenOffscreen();
context.ShowMeshes();
context.DisposeOnGameObjectDestroyed();
Selection.activeGameObject = context.Root;
}
}
static void ImportAsset(string path, UnityPath prefabPath)
{
if (!prefabPath.IsUnderAssetsFolder)
{
Debug.LogWarningFormat("out of asset path: {0}", prefabPath);
return;
}
// import as asset
// var prefabPath = UnityPath.FromUnityPath(prefabPath);
var parser = new GltfParser();
parser.ParseGlb(File.ReadAllBytes(path));
Action<IEnumerable<UnityPath>> onCompleted = texturePaths =>
{
//
// after textures imported
//
var map = texturePaths.Select(x =>
{
Debug.LogWarningFormat("disallow import from folder under the Assets");
return;
}
var texture = x.LoadAsset<Texture2D>() as UnityEngine.Object;
return (texture.name, texture);
}).ToArray();
var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab");
if (string.IsNullOrEmpty(path))
{
return;
}
if (!assetPath.StartsWithUnityAssetPath())
{
Debug.LogWarningFormat("out of asset path: {0}", assetPath);
return;
}
// import as asset
var prefabPath = UnityPath.FromUnityPath(assetPath);
var parser = new GltfParser();
parser.ParseGlb(File.ReadAllBytes(path));
Action<IEnumerable<string>> onCompleted = texturePaths =>
{
//
// after textures imported
//
var map = texturePaths.Select(x =>
{
var texture = AssetDatabase.LoadAssetAtPath(x, typeof(Texture2D));
return (texture.name, texture);
}).ToArray();
using (var context = new VRMImporterContext(parser))
{
var editor = new VRMEditorImporterContext(context, prefabPath);
foreach (var textureInfo in new VRMTextureEnumerator(context.VRM).Enumerate(parser.GLTF))
{
TextureImporterConfigurator.Configure(textureInfo, map.ToDictionary(x => x.name, x => x.texture as Texture2D));
}
context.Load();
editor.SaveAsAsset();
}
};
using (var context = new VRMImporterContext(parser))
using (var context = new VRMImporterContext(parser, null, map))
{
var editor = new VRMEditorImporterContext(context, prefabPath);
editor.ConvertAndExtractImages(UnityPath.FromFullpath(path), onCompleted);
foreach (var textureInfo in new VRMTextureEnumerator(context.VRM).Enumerate(parser.GLTF))
{
TextureImporterConfigurator.Configure(textureInfo, map.ToDictionary(x => x.name, x => x.texture as Texture2D));
}
context.Load();
editor.SaveAsAsset();
}
};
using (var context = new VRMImporterContext(parser))
{
var editor = new VRMEditorImporterContext(context, prefabPath);
editor.ConvertAndExtractImages(onCompleted);
}
}
}

View File

@@ -37,24 +37,24 @@ namespace VRM
}
}
static void ImportVrm(UnityPath path)
static void ImportVrm(UnityPath vrmPath)
{
if (!path.IsUnderAssetsFolder)
if (!vrmPath.IsUnderAssetsFolder)
{
throw new Exception();
}
var parser = new GltfParser();
parser.ParseGlb(File.ReadAllBytes(path.FullPath));
parser.ParseGlb(File.ReadAllBytes(vrmPath.FullPath));
var prefabPath = path.Parent.Child(path.FileNameWithoutExtension + ".prefab");
var prefabPath = vrmPath.Parent.Child(vrmPath.FileNameWithoutExtension + ".prefab");
Action<IEnumerable<string>> onCompleted = texturePaths =>
Action<IEnumerable<UnityPath>> onCompleted = texturePaths =>
{
var map = texturePaths.Select(x =>
{
var texture = AssetDatabase.LoadAssetAtPath(x, typeof(Texture2D));
return (texture.name, texture);
var texture = x.LoadAsset<Texture2D>();
return (texture.name, texture: texture as UnityEngine.Object);
}).ToArray();
using (var context = new VRMImporterContext(parser, null, map))
@@ -73,7 +73,7 @@ namespace VRM
using (var context = new VRMImporterContext(parser))
{
var editor = new VRMEditorImporterContext(context, prefabPath);
editor.ConvertAndExtractImages(path, onCompleted);
editor.ConvertAndExtractImages(onCompleted);
}
}
}