/// <summary> /// SubAssetを外部ファイルに展開する /// </summary> public static void Extract(ScriptedImporter importer, GltfParser parser) { if (string.IsNullOrEmpty(importer.assetPath)) { return; } var path = $"{Path.GetDirectoryName(importer.assetPath)}/{Path.GetFileNameWithoutExtension(importer.assetPath)}.Extracted"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } // meta { foreach (var asset in importer.GetSubAssets <VRM10MetaObject>(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } } { // expressions foreach (var asset in importer.GetSubAssets <VRM10Expression>(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } // expressions foreach (var asset in importer.GetSubAssets <VRM10ExpressionAvatar>(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } // external な expressionAvatar.Clips に 再代入する var expressionAvatar = importer.GetExternalObjectMap().Select(x => x.Value as VRM10ExpressionAvatar).FirstOrDefault(x => x != null); var expressions = importer.GetExternalObjectMap().Select(x => x.Value as VRM10Expression).Where(x => x != null).ToList(); expressionAvatar.Clips = expressions; var avatarPath = AssetDatabase.GetAssetPath(expressionAvatar); if (!string.IsNullOrEmpty(avatarPath)) { EditorUtility.SetDirty(expressionAvatar); AssetDatabase.WriteImportSettingsIfDirty(avatarPath); } } AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); }
static void Process(Vrm10Data result, ScriptedImporter scriptedImporter, AssetImportContext context, RenderPipelineTypes renderPipeline, bool doNormalize) { // // Import(create unity objects) // var extractedObjects = scriptedImporter.GetExternalObjectMap() .Where(kv => kv.Value != null) .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value); var materialGenerator = GetMaterialDescriptorGenerator(renderPipeline); using (var loader = new Vrm10Importer(result, extractedObjects, materialGenerator: materialGenerator, doNormalize: doNormalize)) { // settings TextureImporters foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable()) { VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures); } var loaded = loader.Load(); loaded.ShowMeshes(); loaded.TransferOwnership((key, o) => { context.AddObjectToAsset(key.Name, o); }); var root = loaded.Root; GameObject.DestroyImmediate(loaded); context.AddObjectToAsset(root.name, root); context.SetMainObject(root); } }
public void OnGUI(ScriptedImporter importer, GltfData data) { if (!HasKeys) { EditorGUILayout.HelpBox("no animations", MessageType.Info); return; } if (CanExtract(importer)) { if (GUILayout.Button("Extract Animation ...")) { Extract(importer, data); } EditorGUILayout.HelpBox("Extract subasset to external object and overwrite remap", MessageType.Info); } else { if (GUILayout.Button("Clear extraction")) { ClearExternalObjects(importer, typeof(AnimationClip)); } EditorGUILayout.HelpBox("Clear remap. All remap use subAsset", MessageType.Info); } DrawRemapGUI <AnimationClip>(importer.GetExternalObjectMap()); }
public static void OnGUIMaterial(ScriptedImporter importer, GltfParser parser) { var canExtract = !importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D); using (new TmpGuiEnable(canExtract)) { if (GUILayout.Button("Extract Materials And Textures ...")) { ExtractMaterialsAndTextures(importer); } } // // Draw ExternalObjectMap // s_foldMaterials = EditorGUILayout.Foldout(s_foldMaterials, "Remapped Materials"); if (s_foldMaterials) { DrawRemapGUI <UnityEngine.Material>(importer, parser.GLTF.materials.Select(x => x.name)); } s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures"); if (s_foldTextures) { DrawRemapGUI <UnityEngine.Texture2D>(importer, GltfTextureEnumerator.Enumerate(parser.GLTF).Select(x => x.ConvertedName)); } if (GUILayout.Button("Clear")) { importer.ClearExternalObjects <UnityEngine.Material>(); importer.ClearExternalObjects <UnityEngine.Texture2D>(); } }
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)) { if (GUILayout.Button("Extract Meta And Expressions ...")) { Extract(importer, parser); } } // meta importer.DrawRemapGUI <VRM10MetaObject>(new SubAssetKey[] { VRM10MetaObject.SubAssetKey }); // expression avatar importer.DrawRemapGUI <VRM10ExpressionAvatar>(new SubAssetKey[] { VRM10ExpressionAvatar.SubAssetKey }); // expressions importer.DrawRemapGUI <VRM10Expression>(vrm.Expressions.Select(x => CreateKey(x).SubAssetKey)); if (GUILayout.Button("Clear")) { importer.ClearExternalObjects <VRM10MetaObject>(); importer.ClearExternalObjects <VRM10ExpressionAvatar>(); importer.ClearExternalObjects <VRM10Expression>(); } }
static void DrawRemapGUI <T>(ScriptedImporter importer, IEnumerable <string> names) where T : UnityEngine.Object { EditorGUI.indentLevel++; var map = importer.GetExternalObjectMap() .Select(x => (x.Key.name, x.Value as T)) .Where(x => x.Item2 != null) .ToDictionary(x => x.Item1, x => x.Item2) ; foreach (var name in names) { if (string.IsNullOrEmpty(name)) { throw new System.ArgumentNullException(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(name); map.TryGetValue(name, out T value); var asset = EditorGUILayout.ObjectField(value, typeof(T), true) as T; if (asset != value) { importer.SetExternalUnityObject(new AssetImporter.SourceAssetIdentifier(value), asset); } EditorGUILayout.EndHorizontal(); } EditorGUI.indentLevel--; }
/// <summary> /// SubAssetを外部ファイルに展開する /// </summary> public static void Extract(ScriptedImporter importer, GltfParser parser) { if (string.IsNullOrEmpty(importer.assetPath)) { return; } // meta { var path = GetAndCreateFolder(importer.assetPath, ".Meta"); foreach (var(key, asset) in importer.GetSubAssets <VRM10MetaObject>(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } } { // expressions var path = GetAndCreateFolder(importer.assetPath, ".Expressions"); foreach (var(key, asset) in importer.GetSubAssets <VRM10Expression>(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } } { // expressions var path = GetAndCreateFolder(importer.assetPath, ".ExpressionAvatar"); foreach (var(key, asset) in importer.GetSubAssets <VRM10ExpressionAvatar>(importer.assetPath)) { asset.ExtractSubAsset($"{path}/{asset.name}.asset", false); } // external な expressionAvatar.Clips に 再代入する var expressionAvatar = importer.GetExternalObjectMap().Select(x => x.Value as VRM10ExpressionAvatar).FirstOrDefault(x => x != null); var expressions = importer.GetExternalObjectMap().Select(x => x.Value as VRM10Expression).Where(x => x != null).ToList(); expressionAvatar.Clips = expressions; var avatarPath = AssetDatabase.GetAssetPath(expressionAvatar); if (!string.IsNullOrEmpty(avatarPath)) { EditorUtility.SetDirty(expressionAvatar); AssetDatabase.WriteImportSettingsIfDirty(avatarPath); } } AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); }
public static void ClearExtarnalObjects(this ScriptedImporter importer) { foreach (var extarnalObject in importer.GetExternalObjectMap()) { importer.RemoveRemap(extarnalObject.Key); } AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath); AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); }
public static void ClearExternalObjects <T>(this ScriptedImporter importer) where T : UnityEngine.Object { foreach (var externalObject in importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T))) { importer.RemoveRemap(externalObject.Key); } AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath); AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate); }
public static void OnGUIMaterial(ScriptedImporter importer, GltfParser parser) { var canExtract = !importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D); using (new TmpGuiEnable(canExtract)) { if (GUILayout.Button("Extract Materials And Textures ...")) { ExtractMaterialsAndTextures(importer, parser); } } // // Draw ExternalObjectMap // s_foldMaterials = EditorGUILayout.Foldout(s_foldMaterials, "Remapped Materials"); if (s_foldMaterials) { DrawRemapGUI <UnityEngine.Material>(importer, parser.GLTF.materials.Select(x => x.name)); } s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures"); if (s_foldTextures) { var names = GltfTextureEnumerator.Enumerate(parser) .Select(x => { if (x.TextureType != TextureImportTypes.StandardMap && !string.IsNullOrEmpty(x.Uri)) { // GLTF の 無変換テクスチャーをスキップする return(null); } switch (x.TextureType) { case TextureImportTypes.NormalMap: return(x.GltfName); default: return(x.ConvertedName); } }) .Where(x => !string.IsNullOrEmpty(x)) ; DrawRemapGUI <UnityEngine.Texture2D>(importer, names); } if (GUILayout.Button("Clear")) { importer.ClearExternalObjects <UnityEngine.Material>(); importer.ClearExternalObjects <UnityEngine.Texture2D>(); } }
public void OnGUI(ScriptedImporter importer, GltfData data, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm) { if (CanExtract(importer)) { if (GUILayout.Button("Extract Meta And Expressions ...")) { Extract(importer, data); } EditorGUILayout.HelpBox("Extract subasset to external object and overwrite remap", MessageType.Info); } else { if (GUILayout.Button("Clear extraction")) { ClearExternalObjects(importer, typeof(VRM10Object), typeof(VRM10Expression)); } EditorGUILayout.HelpBox("Clear remap. All remap use subAsset", MessageType.Info); } DrawRemapGUI <VRM10Object>(importer.GetExternalObjectMap()); DrawRemapGUI <VRM10Expression>(importer.GetExternalObjectMap()); }
public void OnGUI(ScriptedImporter importer, GltfData data, ITextureDescriptorGenerator textureDescriptorGenerator, Func <string, string> textureDir, Func <string, string> materialDir) { if (CanExtract(importer)) { if (GUILayout.Button("Extract Materials And Textures ...")) { ExtractMaterialsAndTextures(importer, data, 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); } // // Draw ExternalObjectMap // s_foldMaterials = EditorGUILayout.Foldout(s_foldMaterials, "Remapped Materials"); if (s_foldMaterials) { DrawRemapGUI <UnityEngine.Material>(importer.GetExternalObjectMap()); } s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures"); if (s_foldTextures) { DrawRemapGUI <UnityEngine.Texture>(importer.GetExternalObjectMap()); } }
/// <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); }
/// <summary> /// glb をパースして、UnityObject化、さらにAsset化する /// </summary> /// <param name="scriptedImporter"></param> /// <param name="context"></param> /// <param name="reverseAxis"></param> public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axises reverseAxis) { #if VRM_DEVELOP Debug.Log("OnImportAsset to " + scriptedImporter.assetPath); #endif // // Parse(parse glb, parser gltf json) // var parser = new GltfParser(); parser.ParsePath(scriptedImporter.assetPath); // // Import(create unity objects) // var externalObjectMap = scriptedImporter.GetExternalObjectMap(); using (var loaded = new ImporterContext(parser, null, externalObjectMap.Where(x => x.Value != null).Select(x => (x.Value.name, x.Value)).Concat( EnumerateTexturesFromUri(externalObjectMap, parser, UnityPath.FromUnityPath(scriptedImporter.assetPath).Parent)))) { // settings TextureImporters foreach (var textureInfo in GltfTextureEnumerator.Enumerate(parser.GLTF)) { TextureImporterConfigurator.Configure(textureInfo, loaded.TextureFactory.ExternalMap); } loaded.InvertAxis = reverseAxis; loaded.Load(); loaded.ShowMeshes(); loaded.TransferOwnership(o => { #if VRM_DEVELOP Debug.Log($"[{o.GetType().Name}] {o.name} will not destroy"); #endif context.AddObjectToAsset(o.name, o); if (o is GameObject) { // Root GameObject is main object context.SetMainObject(loaded.Root); } return(true); }); } }
/// <summary> /// /// </summary> /// <param name="scriptedImporter"></param> /// <param name="context"></param> /// <param name="migrateToVrm1">vrm0 だった場合に vrm1 化する</param> /// <param name="renderPipeline"></param> /// <param name="doNormalize">normalize する</param> public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, bool migrateToVrm1, RenderPipelineTypes renderPipeline, bool doNormalize) { #if VRM_DEVELOP Debug.Log("OnImportAsset to " + scriptedImporter.assetPath); #endif using (var data = Vrm10Data.ParseOrMigrate(scriptedImporter.assetPath, migrateToVrm1, out Vrm10Data result, out MigrationData migration)) { if (result == null) { // fail to parse vrm1 return; } // // Import(create unity objects) // var extractedObjects = scriptedImporter.GetExternalObjectMap() .Where(kv => kv.Value != null) .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value); var materialGenerator = GetMaterialDescriptorGenerator(renderPipeline); using (var loader = new Vrm10Importer(result, extractedObjects, materialGenerator: materialGenerator, doNormalize: doNormalize)) { // settings TextureImporters foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable()) { VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures); } var loaded = loader.Load(); loaded.ShowMeshes(); loaded.TransferOwnership((key, o) => { context.AddObjectToAsset(key.Name, o); }); var root = loaded.Root; GameObject.DestroyImmediate(loaded); context.AddObjectToAsset(root.name, root); context.SetMainObject(root); } } }
/// <summary> /// glb をパースして、UnityObject化、さらにAsset化する /// </summary> /// <param name="scriptedImporter"></param> /// <param name="context"></param> /// <param name="reverseAxis"></param> protected static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axes reverseAxis, RenderPipelineTypes renderPipeline) { #if VRM_DEVELOP Debug.Log("OnImportAsset to " + scriptedImporter.assetPath); #endif // // Parse(parse glb, parser gltf json) // var data = new AutoGltfFileParser(scriptedImporter.assetPath).Parse(); // // Import(create unity objects) // // 2 回目以降の Asset Import において、 Importer の設定で Extract した UnityEngine.Object が入る var extractedObjects = scriptedImporter.GetExternalObjectMap() .Where(x => x.Value != null) .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value); IMaterialDescriptorGenerator materialGenerator = GetMaterialGenerator(renderPipeline); using (var loader = new ImporterContext(data, extractedObjects, materialGenerator: materialGenerator)) { // Configure TextureImporter to Extracted Textures. foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable()) { TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures); } loader.InvertAxis = reverseAxis; var loaded = loader.Load(); loaded.ShowMeshes(); loaded.TransferOwnership((k, o) => { context.AddObjectToAsset(k.Name, o); }); var root = loaded.Root; GameObject.DestroyImmediate(loaded); context.AddObjectToAsset(root.name, root); context.SetMainObject(root); } }
public static void OnGUI(ScriptedImporter importer, GltfParser parser, EnumerateAllTexturesDistinctFunc enumTextures) { var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D); using (new TmpGuiEnable(!hasExternal)) { if (GUILayout.Button("Extract Materials And Textures ...")) { ExtractMaterialsAndTextures(importer, parser, enumTextures); } } // // Draw ExternalObjectMap // s_foldMaterials = EditorGUILayout.Foldout(s_foldMaterials, "Remapped Materials"); if (s_foldMaterials) { importer.DrawRemapGUI <UnityEngine.Material>(parser.GLTF.materials.Select(x => new SubAssetKey(typeof(Material), x.name))); } s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures"); if (s_foldTextures) { importer.DrawRemapGUI <UnityEngine.Texture2D>(enumTextures(parser) .Where(x => { var(key, param) = x; if ((param.TextureType == TextureImportTypes.sRGB || param.TextureType == TextureImportTypes.NormalMap) && !string.IsNullOrEmpty(param.Uri)) { // GLTF の 無変換テクスチャーをスキップする return(false); } return(true); }) .Select(x => x.Key) ); } if (GUILayout.Button("Clear")) { importer.ClearExternalObjects <UnityEngine.Material>(); importer.ClearExternalObjects <UnityEngine.Texture2D>(); } }
/// <summary> /// glb をパースして、UnityObject化、さらにAsset化する /// </summary> /// <param name="scriptedImporter"></param> /// <param name="context"></param> /// <param name="reverseAxis"></param> public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axises reverseAxis) { #if VRM_DEVELOP Debug.Log("OnImportAsset to " + scriptedImporter.assetPath); #endif // // Parse(parse glb, parser gltf json) // var parser = new GltfParser(); parser.ParsePath(scriptedImporter.assetPath); // // Import(create unity objects) // var externalObjectMap = scriptedImporter.GetExternalObjectMap().Select(kv => (kv.Value.name, kv.Value)).ToArray(); var externalTextures = EnumerateTexturesFromUri(externalObjectMap, parser, UnityPath.FromUnityPath(scriptedImporter.assetPath).Parent).ToArray(); using (var loader = new ImporterContext(parser, externalObjectMap.Concat(externalTextures))) { // settings TextureImporters foreach (var(key, textureInfo) in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser)) { TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap); } loader.InvertAxis = reverseAxis; loader.Load(); loader.ShowMeshes(); loader.TransferOwnership(o => { context.AddObjectToAsset(o.name, o); if (o is GameObject) { // Root GameObject is main object context.SetMainObject(loader.Root); } return(true); }); } }
public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, bool migrateToVrm1) { #if VRM_DEVELOP Debug.Log("OnImportAsset to " + scriptedImporter.assetPath); #endif var parser = Parse(scriptedImporter.assetPath, migrateToVrm1); if (parser == null) { // fail to parse vrm1 return; } // // Import(create unity objects) // var externalObjectMap = scriptedImporter.GetExternalObjectMap().Select(kv => (kv.Value.name, kv.Value)).ToArray(); using (var loader = new RuntimeUnityBuilder(parser, externalObjectMap)) { // settings TextureImporters foreach (var textureInfo in Vrm10MToonMaterialImporter.EnumerateAllTexturesDistinct(parser)) { TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap); } loader.Load(); loader.ShowMeshes(); loader.TransferOwnership(o => { context.AddObjectToAsset(o.name, o); if (o is GameObject) { // Root GameObject is main object context.SetMainObject(loader.Root); } return(true); }); } }
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); }