Merge pull request #998 from ousttrue/feature/animation_extract

Feature/animation extract
This commit is contained in:
ousttrue 2021-06-03 15:34:49 +09:00 committed by GitHub
commit 1cec8cfcea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 120 additions and 74 deletions

View File

@ -1,16 +1,63 @@
using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Experimental.AssetImporters;
using UnityEngine;
using VRMShaders;
namespace UniGLTF
{
public static class EditorAnimation
{
public static void OnGUIAnimation(GltfParser parser)
public static void OnGUIAnimation(ScriptedImporter importer, GltfParser parser)
{
for (int i = 0; i < parser.GLTF.animations.Count; ++i)
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is AnimationClip);
using (new EditorGUI.DisabledScope(hasExternal))
{
var a = parser.GLTF.animations[i];
GUILayout.Label($"{i}: {a.name}");
if (GUILayout.Button("Extract Animation ..."))
{
Extract(importer, parser);
}
}
importer.DrawRemapGUI<AnimationClip>(parser.GLTF.animations.Select(x => new SubAssetKey(typeof(AnimationClip), x.name)));
if (GUILayout.Button("Clear"))
{
importer.ClearExternalObjects(
typeof(UnityEngine.AnimationClip)
);
}
}
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;
}
public static void Extract(ScriptedImporter importer, GltfParser parser)
{
if (string.IsNullOrEmpty(importer.assetPath))
{
return;
}
{
var path = GetAndCreateFolder(importer.assetPath, ".Animations");
foreach (var (key, asset) in importer.GetSubAssets<AnimationClip>(importer.assetPath))
{
asset.ExtractSubAsset($"{path}/{asset.name}.asset", false);
}
}
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
}
}
}

View File

@ -14,20 +14,6 @@ using UnityEditor.Experimental.AssetImporters;
namespace UniGLTF
{
public class TmpGuiEnable : IDisposable
{
bool m_backup;
public TmpGuiEnable(bool enable)
{
m_backup = GUI.enabled;
GUI.enabled = enable;
}
public void Dispose()
{
GUI.enabled = m_backup;
}
}
public static class EditorMaterial
{
static bool s_foldMaterials = true;
@ -36,7 +22,7 @@ namespace UniGLTF
public static void OnGUI(ScriptedImporter importer, GltfParser parser, ITextureDescriptorGenerator textureDescriptorGenerator, Func<string, string> textureDir, Func<string, string> materialDir)
{
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D);
using (new TmpGuiEnable(!hasExternal))
using (new EditorGUI.DisabledScope(hasExternal))
{
if (GUILayout.Button("Extract Materials And Textures ..."))
{

View File

@ -45,7 +45,7 @@ namespace UniGLTF
break;
case Tabs.Animation:
EditorAnimation.OnGUIAnimation(m_parser);
EditorAnimation.OnGUIAnimation(m_importer, m_parser);
break;
case Tabs.Materials:

View File

@ -45,7 +45,7 @@ namespace UniGLTF
break;
case Tabs.Animation:
EditorAnimation.OnGUIAnimation(m_parser);
EditorAnimation.OnGUIAnimation(m_importer, m_parser);
break;
case Tabs.Materials:

View File

@ -1,10 +1,11 @@
using System.Collections.Generic;
using UnityEngine;
using VRMShaders;
namespace UniGLTF
{
public interface IAnimationImporter
{
List<AnimationClip> Import(glTF gltf, GameObject root, List<Transform> nodes, Axes invertAxis);
AnimationClip Import(glTF gltf, int i, Axes invertAxis);
}
}

View File

@ -1,53 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine;
namespace UniGLTF
{
public sealed class RootAnimationImporter : IAnimationImporter
{
public List<AnimationClip> Import(glTF gltf, GameObject root, List<Transform> _nodes, Axes invertAxis)
public AnimationClip Import(glTF gltf, int i, Axes invertAxis)
{
var animationClips = new List<AnimationClip>();
if (gltf.animations != null && gltf.animations.Any())
{
var animation = root.AddComponent<Animation>();
animationClips.AddRange(ImportAnimationClips(gltf, invertAxis));
foreach (var clip in animationClips)
{
animation.AddClip(clip, clip.name);
}
if (animationClips.Count > 0)
{
animation.clip = animationClips.First();
}
}
return animationClips;
}
private IEnumerable<AnimationClip> ImportAnimationClips(glTF gltf, Axes invertAxis)
{
for (var i = 0; i < gltf.animations.Count; ++i)
{
var clip = new AnimationClip();
clip.ClearCurves();
clip.legacy = true;
clip.name = gltf.animations[i].name;
if (string.IsNullOrEmpty(clip.name))
{
clip.name = $"legacy_{i}";
}
clip.wrapMode = WrapMode.Loop;
var animation = gltf.animations[i];
if (string.IsNullOrEmpty(animation.name))
{
animation.name = $"animation:{i}";
}
yield return AnimationImporterUtil.ConvertAnimationClip(gltf, animation, invertAxis.Create());
}
return AnimationImporterUtil.ConvertAnimationClip(gltf, gltf.animations[i], invertAxis.Create());
}
}
}

View File

@ -130,13 +130,14 @@ namespace UniGLTF
RestoreOlderVersionValues();
FixMeshNameUnique();
foreach(var image in GLTF.images)
foreach (var image in GLTF.images)
{
image.uri = PrepareUri(image.uri);
}
FixTextureNameUnique();
FixMaterialNameUnique();
FixNodeName();
FixAnimationNameUnique();
// parepare byte buffer
//GLTF.baseDir = System.IO.Path.GetDirectoryName(Path);
@ -308,6 +309,34 @@ namespace UniGLTF
}
}
void FixAnimationNameUnique()
{
var used = new HashSet<string>();
for (int i = 0; i < GLTF.animations.Count; ++i)
{
var animation = GLTF.animations[i];
var originalName = animation.name;
int j = 2;
if (string.IsNullOrEmpty(animation.name))
{
animation.name = $"animation_{i}";
}
while (true)
{
if (used.Add(animation.name))
{
#if VRM_DEVELOP
// Debug.Log($"Material: {material.name}");
#endif
break;
}
animation.name = string.Format("{0}({1})", originalName, j++);
}
}
}
void RestoreOlderVersionValues()
{
var parsed = UniJSON.JsonParser.Parse(Json);

View File

@ -36,6 +36,7 @@ namespace UniGLTF
public IMaterialDescriptorGenerator MaterialDescriptorGenerator { get; protected set; }
public TextureFactory TextureFactory { get; }
public MaterialFactory MaterialFactory { get; }
IReadOnlyDictionary<SubAssetKey, UnityEngine.Object> _externalObjectMap;
public ImporterContext(
GltfParser parser,
@ -46,13 +47,13 @@ namespace UniGLTF
TextureDescriptorGenerator = new GltfTextureDescriptorGenerator(Parser);
MaterialDescriptorGenerator = new GltfMaterialDescriptorGenerator();
externalObjectMap = externalObjectMap ?? new Dictionary<SubAssetKey, UnityEngine.Object>();
_externalObjectMap = externalObjectMap ?? new Dictionary<SubAssetKey, UnityEngine.Object>();
textureDeserializer = textureDeserializer ?? new UnityTextureDeserializer();
TextureFactory = new TextureFactory(textureDeserializer, externalObjectMap
TextureFactory = new TextureFactory(textureDeserializer, _externalObjectMap
.Where(x => x.Value is Texture)
.ToDictionary(x => x.Key, x => (Texture)x.Value));
MaterialFactory = new MaterialFactory(externalObjectMap
MaterialFactory = new MaterialFactory(_externalObjectMap
.Where(x => x.Value is Material)
.ToDictionary(x => x.Key, x => (Material)x.Value));
}
@ -122,7 +123,30 @@ namespace UniGLTF
using (MeasureTime("AnimationImporter"))
{
AnimationClips.AddRange(AnimationImporter.Import(GLTF, Root, null, InvertAxis));
if (GLTF.animations != null && GLTF.animations.Any())
{
var animation = Root.AddComponent<Animation>();
for (int i = 0; i < GLTF.animations.Count; ++i)
{
var gltfAnimation = GLTF.animations[i];
AnimationClip clip = default;
if (_externalObjectMap.TryGetValue(new SubAssetKey(typeof(AnimationClip), gltfAnimation.name), out UnityEngine.Object value))
{
clip = value as AnimationClip;
}
else
{
clip = AnimationImporter.Import(GLTF, i, InvertAxis);
AnimationClips.Add(clip);
}
animation.AddClip(clip, clip.name);
if (i == 0)
{
animation.clip = clip;
}
}
}
}
await OnLoadHierarchy(awaitCaller, MeasureTime);

View File

@ -69,7 +69,7 @@ namespace UniVRM10
public override void OnInspectorGUI()
{
// select sub editor
using (new EditorGUI.DisabledGroupScope(false))
using (new EditorGUI.DisabledScope(false))
{
_tab = (Tabs)EditorGUILayout.EnumPopup("Select GUI", _tab);
EditorGUILayout.Separator();

View File

@ -173,7 +173,7 @@ namespace UniVRM10
}
}
using (new EditorGUI.DisabledGroupScope(true))
using (new EditorGUI.DisabledScope(true))
{
if (m_constraints != null)
{

View File

@ -30,7 +30,7 @@ namespace UniVRM10
public static void OnGUI(ScriptedImporter importer, GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)
{
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is VRM10MetaObject || x.Value is VRM10ExpressionAvatar || x.Value is VRM10Expression);
using (new TmpGuiEnable(!hasExternal))
using (new EditorGUI.DisabledScope(hasExternal))
{
if (GUILayout.Button("Extract Meta And Expressions ..."))
{