Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract/Clear 改修 #1073

Merged
merged 5 commits into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Experimental.AssetImporters;
Expand All @@ -17,26 +14,30 @@ public RemapEditorAnimation(IEnumerable<SubAssetKey> keys, EditorMapGetterFunc g

public void OnGUI(ScriptedImporter importer, GltfParser parser)
{
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is AnimationClip);
using (new EditorGUI.DisabledScope(hasExternal))
if (!HasKeys)
{
EditorGUILayout.HelpBox("no animations", MessageType.Info);
return;
}

if (CanExtract(importer))
{
if (GUILayout.Button("Extract Animation ..."))
{
Extract(importer, parser);
}
EditorGUILayout.HelpBox("Extract subasset to external object and overwrite remap", MessageType.Info);
}

DrawRemapGUI<AnimationClip>(importer.GetExternalObjectMap());
}

static string GetAndCreateFolder(string assetPath, string suffix)
{
var path = $"{Path.GetDirectoryName(assetPath)}/{Path.GetFileNameWithoutExtension(assetPath)}{suffix}";
if (!Directory.Exists(path))
else
{
Directory.CreateDirectory(path);
if (GUILayout.Button("Clear extraction"))
{
ClearExternalObjects(importer, typeof(AnimationClip));
}
EditorGUILayout.HelpBox("Clear remap. All remap use subAsset", MessageType.Info);
}
return path;

DrawRemapGUI<AnimationClip>(importer.GetExternalObjectMap());
}

public static void Extract(ScriptedImporter importer, GltfParser parser)
Expand All @@ -46,12 +47,12 @@ public static void Extract(ScriptedImporter importer, GltfParser parser)
return;
}


var path = GetAndCreateFolder(importer.assetPath, ".Animations");
foreach (var asset in AssetDatabase.LoadAllAssetsAtPath(importer.assetPath))
{
var path = GetAndCreateFolder(importer.assetPath, ".Animations");
foreach (var (key, asset) in importer.GetSubAssets<AnimationClip>(importer.assetPath))
if (asset is AnimationClip)
{
asset.ExtractSubAsset($"{path}/{asset.name}.asset", false);
ExtractSubAsset(asset, $"{path}/{asset.name}.asset", false);
}
}

Expand Down
102 changes: 98 additions & 4 deletions Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/RemapEditorBase.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Experimental.AssetImporters;
Expand All @@ -13,7 +14,18 @@ namespace UniGLTF

public abstract class RemapEditorBase
{
public static Dictionary<String, Type> s_typeMap = new Dictionary<string, Type>();
static Dictionary<String, Type> s_typeMap;
static Dictionary<String, Type> TypeMap
{
get
{
if (s_typeMap == null)
{
s_typeMap = new Dictionary<string, Type>();
}
return s_typeMap;
}
}

[Serializable]
public struct SubAssetPair
Expand All @@ -24,16 +36,16 @@ public struct SubAssetPair
[SerializeField]
public String Name;

public SubAssetKey Key => new SubAssetKey(s_typeMap[Type], Name);
public ScriptedImporter.SourceAssetIdentifier ID => new AssetImporter.SourceAssetIdentifier(s_typeMap[Type], Name);
public SubAssetKey Key => new SubAssetKey(TypeMap[Type], Name);
public ScriptedImporter.SourceAssetIdentifier ID => new AssetImporter.SourceAssetIdentifier(TypeMap[Type], Name);

[SerializeField]
public UnityEngine.Object Object;

public SubAssetPair(SubAssetKey key, UnityEngine.Object o)
{
Type = key.Type.ToString();
s_typeMap[Type] = key.Type;
TypeMap[Type] = key.Type;
Name = key.Name;
Object = o;
}
Expand All @@ -46,6 +58,8 @@ public SubAssetPair(SubAssetKey key, UnityEngine.Object o)
/// </summary>
SubAssetKey[] m_keys;

protected bool HasKeys => m_keys.Length > 0;

EditorMapGetterFunc m_getter;
EditorMapSetterFunc m_setter;

Expand All @@ -56,6 +70,27 @@ protected RemapEditorBase(IEnumerable<SubAssetKey> keys, EditorMapGetterFunc get
m_setter = setter;
}

/// <summary>
/// Extract 対象がすべて SubAsset に含まれるときに可能である
/// </summary>
/// <param name="importer"></param>
/// <returns></returns>
protected bool CanExtract(ScriptedImporter importer)
{
foreach (var (k, v) in importer.GetExternalObjectMap())
{
foreach (var key in m_keys)
{
if (k.type.IsAssignableFrom(key.Type))
{
return false;
}
}
}

return true;
}

protected void DrawRemapGUI<T>(
Dictionary<ScriptedImporter.SourceAssetIdentifier, UnityEngine.Object> externalObjectMap
) where T : UnityEngine.Object
Expand Down Expand Up @@ -97,5 +132,64 @@ protected void DrawRemapGUI<T>(
}
EditorGUI.indentLevel--;
}

protected static string GetAndCreateFolder(string assetPath, string suffix)
{
var path = $"{Path.GetDirectoryName(assetPath)}/{Path.GetFileNameWithoutExtension(assetPath)}{suffix}";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
return path;
}

/// <summary>
/// subAsset を 指定された path に extract する
/// </summary>
/// <param name="subAsset"></param>
/// <param name="destinationPath"></param>
/// <param name="isForceUpdate"></param>
public static UnityEngine.Object ExtractSubAsset(UnityEngine.Object subAsset, string destinationPath, bool isForceUpdate)
{
string assetPath = AssetDatabase.GetAssetPath(subAsset);

// clone を path に出力(subAsset を出力するため)
var clone = UnityEngine.Object.Instantiate(subAsset);
AssetDatabase.CreateAsset(clone, destinationPath);

// subAsset を clone に対して remap する
var assetImporter = AssetImporter.GetAtPath(assetPath);
assetImporter.AddRemap(new AssetImporter.SourceAssetIdentifier(clone), clone);

if (isForceUpdate)
{
AssetDatabase.WriteImportSettingsIfDirty(assetPath);
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
}

return clone;
}

public static void ClearExternalObjects(ScriptedImporter importer, params Type[] targetTypes)
{
foreach (var targetType in targetTypes)
{
if (!typeof(UnityEngine.Object).IsAssignableFrom(targetType))
{
throw new NotImplementedException();
}

foreach (var (key, obj) in importer.GetExternalObjectMap())
{
if (targetType.IsAssignableFrom(key.type))
{
importer.RemoveRemap(key);
}
}
}

AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath);
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,21 @@ public void OnGUI(ScriptedImporter importer, GltfParser parser,
Func<string, string> textureDir,
Func<string, string> materialDir)
{
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D);
using (new EditorGUI.DisabledScope(hasExternal))
if (CanExtract(importer))
{
if (GUILayout.Button("Extract Materials And Textures ..."))
{
ExtractMaterialsAndTextures(importer, parser, textureDescriptorGenerator, textureDir, materialDir);
}
EditorGUILayout.HelpBox("Extract subasset to external object and overwrite remap", MessageType.Info);
}
else
{
if (GUILayout.Button("Clear extraction"))
{
ClearExternalObjects(importer, typeof(Texture), typeof(Material));
}
EditorGUILayout.HelpBox("Clear remap. All remap use subAsset", MessageType.Info);
}

//
Expand Down Expand Up @@ -72,17 +80,23 @@ void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser, IText
AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);

ExtractMaterials(self, materialDir);
// material extract 後に importer 発動
AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
};

// subAsset を ExternalObject として投入する
var subAssets = AssetDatabase.LoadAllAssetsAtPath(self.assetPath)
.Select(x => x as Texture)
.Where(x => x != null)
.Select(x => (new SubAssetKey(x), x))
.ToDictionary(kv => kv.Item1, kv => kv.Item2)
;

var assetPath = UnityPath.FromFullpath(parser.TargetPath);
var dirName = textureDir(assetPath.Value); // $"{assetPath.FileNameWithoutExtension}.Textures";
TextureExtractor.ExtractTextures(
parser,
assetPath.Parent.Child(dirName),
textureDescriptorGenerator,
self.GetSubAssets<Texture>(self.assetPath).ToDictionary(kv => kv.Item1, kv => kv.Item2),
subAssets,
addRemap,
onCompleted
);
Expand All @@ -94,16 +108,22 @@ public void ExtractMaterials(ScriptedImporter importer, Func<string, string> mat
{
return;
}

var path = $"{Path.GetDirectoryName(importer.assetPath)}/{materialDir(importer.assetPath)}"; // Path.GetFileNameWithoutExtension(importer.assetPath)}.Materials
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}

foreach (var (key, asset) in importer.GetSubAssets<Material>(importer.assetPath))
foreach (var asset in AssetDatabase.LoadAllAssetsAtPath(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{key.Name}.mat", false);
if (asset is Material)
{
ExtractSubAsset(asset, $"{path}/{asset.name}.mat", false);
}
}

AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public void ApplyRemap(ScriptedImporter importer)
importer.RemoveRemap(kv.ID);
}
}
m_editMap.Clear();
AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath);
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
}
Expand Down

This file was deleted.

This file was deleted.

Loading