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

Feature10/vrm1 export #859

Merged
merged 13 commits into from
Apr 9, 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
Expand Up @@ -41,8 +41,16 @@ public GameObject ExportRoot
if (value != null && AssetDatabase.IsMainAsset(value))
{
assetPath = AssetDatabase.GetAssetPath(value);
isPrefab = true;
value = PrefabUtility.LoadPrefabContents(assetPath);
try
{
var prefab = PrefabUtility.LoadPrefabContents(assetPath);
value = prefab;
isPrefab = true;
}
catch (ArgumentException ex)
{
// Debug.LogWarning(ex);
}
}
if (m_root.GameObject == value)
{
Expand Down
1 change: 1 addition & 0 deletions Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,6 @@ public static ArraySegment<T> Slice<T>(this ArraySegment<T> self, int start)
}
return self.Slice(start, self.Count - start);
}

}
}
12 changes: 6 additions & 6 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/MaterialExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ public enum glTFBlendMode

public interface IMaterialExporter
{
glTFMaterial ExportMaterial(Material m, TextureExporter textureManager);
glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter);
}

public class MaterialExporter : IMaterialExporter
{
public virtual glTFMaterial ExportMaterial(Material m, TextureExporter textureManager)
public virtual glTFMaterial ExportMaterial(Material m, TextureExporter textureExporter)
{
var material = CreateMaterial(m);

// common params
material.name = m.name;
Export_Color(m, textureManager, material);
Export_Emission(m, textureManager, material);
Export_Normal(m, textureManager, material);
Export_OcclusionMetallicRoughness(m, textureManager, material);
Export_Color(m, textureExporter, material);
Export_Emission(m, textureExporter, material);
Export_Normal(m, textureExporter, material);
Export_OcclusionMetallicRoughness(m, textureExporter, material);

return material;
}
Expand Down
2 changes: 1 addition & 1 deletion Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
using UnityEngine;
using VRMShaders;


namespace UniGLTF
{
public class gltfExporter : IDisposable
{

protected glTF glTF;

public GameObject Copy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ public class VrmScriptedImporterEditorGUI : ScriptedImporterEditor
VrmLib.Model m_model;
UniGLTF.Extensions.VRMC_vrm.VRMC_vrm m_vrm;

string m_message;

public override void OnEnable()
{
base.OnEnable();

m_importer = target as VrmScriptedImporter;
m_parser = VrmScriptedImporterImpl.Parse(m_importer.assetPath, m_importer.MigrateToVrm1);
if (m_parser == null)
m_message = VrmScriptedImporterImpl.TryParseOrMigrate(m_importer.assetPath, m_importer.MigrateToVrm1, out m_parser);
if (string.IsNullOrEmpty(m_message))
{
// ok
return;
}
if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(m_parser.GLTF.extensions, out m_vrm))
Expand All @@ -45,6 +48,11 @@ enum Tabs

public override void OnInspectorGUI()
{
if (!string.IsNullOrEmpty(m_message))
{
EditorGUILayout.HelpBox(m_message, MessageType.Error);
}

s_currentTab = MeshUtility.TabBar.OnGUI(s_currentTab);
GUILayout.Space(10);

Expand Down
61 changes: 48 additions & 13 deletions Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using UnityEngine;
using UniGLTF;
using System.IO;
using System;
using UniJSON;
#if UNITY_2020_2_OR_NEWER
using UnityEditor.AssetImporters;
#else
Expand All @@ -19,38 +21,71 @@ public static class VrmScriptedImporterImpl
/// <param name="path"></param>
/// <param name="migrateToVrm1"></param>
/// <returns></returns>
public static GltfParser Parse(string path, bool migrateToVrm1)
public static string TryParseOrMigrate(string path, bool migrateToVrm1, out GltfParser parser)
{
//
// Parse(parse glb, parser gltf json)
//
var parser = new GltfParser();
parser = new GltfParser();
parser.ParsePath(path);
if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
{
return parser;
// success
return default;
}

if (migrateToVrm1)
if (!migrateToVrm1)
{
// try migrateion
var migrated = MigrationVrm.Migrate(File.ReadAllBytes(path));
parser = new GltfParser();
parser.Parse(path, migrated);
return parser;
return "vrm1 not found";
}

return null;
// try migrateion
Byte[] migrated = default;
try
{
var src = File.ReadAllBytes(path);
var glb = UniGLTF.Glb.Parse(src);
var json = glb.Json.Bytes.ParseAsJson();
if (!json.TryGet("extensions", out JsonNode extensions))
{
return "no gltf.extensions";
}
if (!extensions.TryGet("VRM", out JsonNode vrm0))
{
return "vrm0 not found";
}

migrated = MigrationVrm.Migrate(json, glb.Binary.Bytes);
if (migrated == null)
{
return "cannot migrate";
}
}
catch (Exception)
{
return "migration error";
}

parser = new GltfParser();
parser.Parse(path, migrated);
if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out vrm))
{
// success
return default;
}

parser = default;
return "migrate but no vrm1. unknown";
}

public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, bool migrateToVrm1)
{
#if VRM_DEVELOP
#if VRM_DEVELOP
Debug.Log("OnImportAsset to " + scriptedImporter.assetPath);
#endif

var parser = Parse(scriptedImporter.assetPath, migrateToVrm1);
if (parser == null)
var message = TryParseOrMigrate(scriptedImporter.assetPath, migrateToVrm1, out GltfParser parser);
if (!string.IsNullOrEmpty(message))
{
// fail to parse vrm1
return;
Expand Down
30 changes: 12 additions & 18 deletions Assets/VRM10/Editor/Vrm10ExportDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
using System.Linq;
using System.Reflection;
using MeshUtility;
using UniGLTF;
using UnityEditor;
using UnityEngine;
using VrmLib;
using VRMShaders;

namespace UniVRM10
{
Expand Down Expand Up @@ -300,8 +302,8 @@ void OnExportClicked(GameObject root)

try
{
var exporter = new UniVRM10.RuntimeVrmConverter();
var model = exporter.ToModelFrom10(root, Meta ? Meta : m_tmpMeta);
var converter = new UniVRM10.RuntimeVrmConverter();
var model = converter.ToModelFrom10(root);

// if (MeshUtility.Validators.HumanoidValidator.HasRotationOrScale(root))
// {
Expand All @@ -315,7 +317,13 @@ void OnExportClicked(GameObject root)
m_logLabel += $"convert to right handed coordinate...\n";
model.ConvertCoordinate(VrmLib.Coordinates.Vrm1, ignoreVrm: false);

var exportedBytes = GetGlb(model);
// export vrm-1.0
var exporter = new UniVRM10.Vrm10Exporter(AssetTextureUtil.IsTextureEditorAsset);
var option = new VrmLib.ExportArgs();
exporter.Export(root, model, converter, option, Meta ? Meta : m_tmpMeta);

var exportedBytes = exporter.Storage.ToBytes();

m_logLabel += $"write to {path}...\n";
File.WriteAllBytes(path, exportedBytes);
Debug.Log("exportedBytes: " + exportedBytes.Length);
Expand All @@ -334,23 +342,9 @@ void OnExportClicked(GameObject root)
}
}

static byte[] GetGlb(VrmLib.Model model)
{
// export vrm-1.0
var exporter = new UniVRM10.Vrm10Exporter();
var option = new VrmLib.ExportArgs
{
// vrm = false
};
var glbBytes10 = exporter.Export(model, option);
// ?
var glb10 = UniGLTF.Glb.Parse(glbBytes10);
return glb10.ToBytes();
}

static string ToAssetPath(string path)
{
var assetPath = UnityPath.FromFullpath(path);
var assetPath = UniGLTF.UnityPath.FromFullpath(path);
return assetPath.Value;
}
}
Expand Down
9 changes: 7 additions & 2 deletions Assets/VRM10/Runtime/Components/VRM10ControllerExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ public sealed class VRM10ControllerExpression
public float LookAtOverrideRate { get; private set; }
public float MouthOverrideRate { get; private set; }

int m_debugCount;

internal void Setup(Transform transform, ILookAtEyeDirectionProvider eyeDirectionProvider, ILookAtEyeDirectionApplicable eyeDirectionApplicable)
{
if (ExpressionAvatar == null)
{
#if VRM_DEVELOP
Debug.LogWarning($"{nameof(VRM10ControllerExpression)}.{nameof(ExpressionAvatar)} is null.");
#if VRM_DEVELOP
if (m_debugCount++ == 0)
{
Debug.LogWarning($"{nameof(VRM10ControllerExpression)}.{nameof(ExpressionAvatar)} is null.");
}
#endif
return;
}
Expand Down
6 changes: 3 additions & 3 deletions Assets/VRM10/Runtime/IO/ModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ public static class ModelExtensions
public static byte[] ToGlb(this VrmLib.Model model)
{
// export vrm-1.0
var exporter10 = new Vrm10Exporter();
var exporter10 = new Vrm10Exporter(_ => false);
var option = new VrmLib.ExportArgs
{
// vrm = false
};
var glbBytes10 = exporter10.Export(model, option);
var glb10 = UniGLTF.Glb.Parse(glbBytes10);
exporter10.Export(null, model, null, option);
var glb10 = UniGLTF.Glb.Parse(exporter10.Storage.ToBytes());
return glb10.ToBytes();
}
}
Expand Down
45 changes: 18 additions & 27 deletions Assets/VRM10/Runtime/IO/RuntimeUnityBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,10 @@ public class RuntimeUnityBuilder : UniGLTF.ImporterContext

UniGLTF.Extensions.VRMC_vrm.VRMC_vrm m_vrm;

List<(string, UnityEngine.Object)> m_external = new List<(string, UnityEngine.Object)>();

public RuntimeUnityBuilder(UniGLTF.GltfParser parser, IEnumerable<(string, UnityEngine.Object)> externalObjectMap = null) : base(parser, externalObjectMap)
{
m_model = VrmLoader.CreateVrmModel(parser);

if (externalObjectMap != null)
{
m_external.AddRange(externalObjectMap);
}

// for `VRMC_materials_mtoon`
this.GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, Vrm10MToonMaterialImporter.TryCreateParam);

Expand Down Expand Up @@ -233,20 +226,22 @@ protected override async Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func<str
await LoadConstraintAsync(awaitCaller, controller);
}

async Task LoadVrmAsync(IAwaitCaller awaitCaller, VRM10Controller controller, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)
static ExpressionKey Key(UniGLTF.Extensions.VRMC_vrm.Expression e)
{
// meta
controller.Meta = m_external.Select(x => x.Item2 as VRM10MetaObject).FirstOrDefault(x => x != null);
// external meta != null のとき m_meta は null になる
if (controller.Meta != null)
if (e.Preset == UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
{
// texture の 取得
if (Vrm10MToonMaterialImporter.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out VRMShaders.TextureImportParam param))
{
var texture = await TextureFactory.GetTextureAsync(param);
}
return ExpressionKey.CreateCustom(e.Name);
}
else
{
return ExpressionKey.CreateFromPreset(e.Preset);
}
else if (vrm.Meta != null)
}

async Task LoadVrmAsync(IAwaitCaller awaitCaller, VRM10Controller controller, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)
{
// meta
if (vrm.Meta != null)
{
var src = vrm.Meta;
m_meta = ScriptableObject.CreateInstance<VRM10MetaObject>();
Expand Down Expand Up @@ -286,8 +281,7 @@ async Task LoadVrmAsync(IAwaitCaller awaitCaller, VRM10Controller controller, Un
}

// expression
controller.Expression.ExpressionAvatar = m_external.Select(x => x.Item2 as VRM10ExpressionAvatar).FirstOrDefault(x => x != null);
if (controller.Expression.ExpressionAvatar == null && vrm.Expressions != null)
if (vrm.Expressions != null)
{
controller.Expression.ExpressionAvatar = ScriptableObject.CreateInstance<VRM10ExpressionAvatar>();

Expand All @@ -299,7 +293,7 @@ async Task LoadVrmAsync(IAwaitCaller awaitCaller, VRM10Controller controller, Un
var clip = ScriptableObject.CreateInstance<UniVRM10.VRM10Expression>();
clip.Preset = expression.Preset;
clip.ExpressionName = expression.Name;
clip.name = expression.ExtractKey();
clip.name = Key(expression).ExtractKey;
clip.IsBinary = expression.IsBinary.GetValueOrDefault();
clip.OverrideBlink = expression.OverrideBlink;
clip.OverrideLookAt = expression.OverrideLookAt;
Expand Down Expand Up @@ -573,15 +567,12 @@ public override void TransferOwnership(Func<UnityEngine.Object, bool> take)
m_humanoid = null;
}

if (m_meta != null)
if (take(m_meta))
{
if (take(m_meta))
{
m_meta = null;
}
m_meta = null;
}

if (m_exressionAvatar != null)
if (m_exressionAvatar != null && m_exressionAvatar.Clips != null)
{
foreach (var x in m_exressionAvatar.Clips)
{
Expand Down
Loading