diff --git a/Assets/VRM10.Samples/Runtime/ViewerUI.cs b/Assets/VRM10.Samples/Runtime/ViewerUI.cs index 1eb40c56e..70bc91699 100644 --- a/Assets/VRM10.Samples/Runtime/ViewerUI.cs +++ b/Assets/VRM10.Samples/Runtime/ViewerUI.cs @@ -311,7 +311,7 @@ namespace UniVRM10.Samples var parser = new UniGLTF.GltfParser(); parser.ParsePath(path); - using (var loader = new RuntimeUnityBuilder(parser)) + using (var loader = new Vrm10Importer(parser)) { loader.Load(); loader.ShowMeshes(); diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs index 7ee835e14..071f61e98 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs @@ -38,7 +38,7 @@ namespace UniVRM10 m_parser = null; return; } - m_model = VrmLoader.CreateVrmModel(m_parser); + m_model = ModelReader.Read(m_parser); } enum Tabs diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs index 4aa87e7f3..1a9bcbceb 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs @@ -96,7 +96,7 @@ namespace UniVRM10 // var externalObjectMap = scriptedImporter.GetExternalObjectMap().ToDictionary(kv => new SubAssetKey(kv.Key.type, kv.Key.name), kv => kv.Value); - using (var loader = new RuntimeUnityBuilder(parser, externalObjectMap)) + using (var loader = new Vrm10Importer(parser, externalObjectMap)) { // settings TextureImporters foreach (var (key, textureInfo) in Vrm10MaterialImporter.EnumerateAllTexturesDistinct(parser)) diff --git a/Assets/VRM10/Editor/Vrm10ExportDialog.cs b/Assets/VRM10/Editor/Vrm10ExportDialog.cs index 40cedcbb7..b321c19b1 100644 --- a/Assets/VRM10/Editor/Vrm10ExportDialog.cs +++ b/Assets/VRM10/Editor/Vrm10ExportDialog.cs @@ -281,7 +281,7 @@ namespace UniVRM10 try { - var converter = new UniVRM10.RuntimeVrmConverter(); + var converter = new UniVRM10.ModelExporter(); var model = converter.ToModelFrom10(root); if (HumanoidValidator.HasRotationOrScale(root)) diff --git a/Assets/VRM10/Runtime/IO/ComponentBuilder.cs b/Assets/VRM10/Runtime/IO/ComponentBuilder.cs deleted file mode 100644 index eace97c9e..000000000 --- a/Assets/VRM10/Runtime/IO/ComponentBuilder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using UnityEngine; -using System.Linq; -using System.Collections.Generic; - -namespace UniVRM10 -{ - public static class ComponentBuilder - { - #region Util - static (Transform, Mesh) GetTransformAndMesh(Transform t) - { - var skinnedMeshRenderer = t.GetComponent(); - if (skinnedMeshRenderer != null) - { - return (t, skinnedMeshRenderer.sharedMesh); - } - - var filter = t.GetComponent(); - if (filter != null) - { - return (t, filter.sharedMesh); - } - - return default; - } - #endregion - } -} diff --git a/Assets/VRM10/Runtime/IO/DictionaryExtensions.cs b/Assets/VRM10/Runtime/IO/DictionaryExtensions.cs deleted file mode 100644 index 5cddb3de7..000000000 --- a/Assets/VRM10/Runtime/IO/DictionaryExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; - -namespace UniVRM10 -{ - public static class DictionaryExtensions - { - public static U GetOrDefault(this Dictionary d, T key) - { - if(key == null) - { - return default; - } - - if(d.TryGetValue(key, out U value)) - { - return value;; - } - else{ - return default; - } - } - } -} diff --git a/Assets/VRM10/Runtime/IO/ExpressionExtensions.cs b/Assets/VRM10/Runtime/IO/ExpressionExtensions.cs index 6abd9aca2..525c51f36 100644 --- a/Assets/VRM10/Runtime/IO/ExpressionExtensions.cs +++ b/Assets/VRM10/Runtime/IO/ExpressionExtensions.cs @@ -7,7 +7,7 @@ namespace UniVRM10 { public static class ExpressionExtensions { - public static UniVRM10.MorphTargetBinding Build10(this MorphTargetBind bind, GameObject root, RuntimeUnityBuilder.ModelMap loader, VrmLib.Model model) + public static UniVRM10.MorphTargetBinding Build10(this MorphTargetBind bind, GameObject root, Vrm10Importer.ModelMap loader, VrmLib.Model model) { var libNode = model.Nodes[bind.Node.Value]; var node = loader.Nodes[libNode].transform; diff --git a/Assets/VRM10/Runtime/IO/MeshAdapter.cs b/Assets/VRM10/Runtime/IO/MeshAdapter.cs deleted file mode 100644 index fcb514a15..000000000 --- a/Assets/VRM10/Runtime/IO/MeshAdapter.cs +++ /dev/null @@ -1,401 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Runtime.InteropServices; -using UniGLTF; -using VrmLib; - -namespace UniVRM10 -{ - public static class MeshAdapter - { - /// - /// VertexBufferはひとつでIndexBufferの参照が異なる - /// - /// VertexBuffer - /// +----------------------------------+ - /// | | - /// +----------------------------------+ - /// A A A - /// | | | - /// +---------+--------+--------+ - /// | submesh0|submesh1|submesh2| - /// +---------+--------+--------+ - /// IndexBuffer - /// - public static Mesh SharedBufferFromGltf(this glTFMesh x, Vrm10Storage storage) - { - // 先頭を使う - return FromGltf(storage, x, x.primitives[0], true); - } - - /// - /// IndexBuffer毎に異なるVertexBufferを参照する - /// - /// VertexBuffer - /// +--------+ +--------+ +--------+ - /// |0 | |1 | |2 | - /// +--------+ +--------+ +--------+ - /// A A A - /// | | | - /// +---------+--------+--------+ - /// | submesh0|submesh1|submesh2| - /// +---------+--------+--------+ - /// IndexBuffer - /// - public static Mesh FromGltf(this glTFPrimitives primitive, Vrm10Storage storage, glTFMesh x) - { - return FromGltf(storage, x, primitive, false); - } - - static Mesh FromGltf(Vrm10Storage storage, glTFMesh x, glTFPrimitives primitive, bool isShared) - { - var mesh = new Mesh((TopologyType)primitive.mode) - { - VertexBuffer = primitive.attributes.FromGltf(storage) - }; - - if (isShared) - { - // create joined index buffer - mesh.IndexBuffer = storage.CreateAccessor(x.primitives.Select(y => y.indices).ToArray()); - } - else - { - mesh.IndexBuffer = storage.CreateAccessor(primitive.indices); - } - - { - gltf_mesh_extras_targetNames.TryGet(x, out List targetNames); - - for (int i = 0; i < primitive.targets.Count; ++i) - { - var gltfTarget = primitive.targets[i]; - - string targetName = null; - { - targetName = targetNames[i]; - } - var target = new MorphTarget(targetName) - { - VertexBuffer = gltfTarget.FromGltf(storage) - }; - - // validate count - foreach (var kv in target.VertexBuffer) - { - if (kv.Value.Count != mesh.VertexBuffer.Count) - { - throw new Exception(); - } - } - - mesh.MorphTargets.Add(target); - } - } - - return mesh; - } - - public static VertexBuffer FromGltf(this glTFAttributes attributes, - Vrm10Storage storage) - { - var b = new VertexBuffer(); - - if (storage.TryCreateAccessor(attributes.POSITION, out BufferAccessor position)) - { - b.Add(VertexBuffer.PositionKey, position); - } - else - { - // position required - throw new Exception(); - } - - if (storage.TryCreateAccessor(attributes.NORMAL, out BufferAccessor normal)) b.Add(VertexBuffer.NormalKey, normal); - if (storage.TryCreateAccessor(attributes.COLOR_0, out BufferAccessor color)) b.Add(VertexBuffer.ColorKey, color); - if (storage.TryCreateAccessor(attributes.TEXCOORD_0, out BufferAccessor tex0)) b.Add(VertexBuffer.TexCoordKey, tex0); - if (storage.TryCreateAccessor(attributes.TEXCOORD_1, out BufferAccessor tex1)) b.Add(VertexBuffer.TexCoordKey2, tex1); - // if(storage.TryCreateAccessor(attributes.TANGENT, out BufferAccessor tangent))b.Add(VertexBuffer.TangentKey, tangent); - if (storage.TryCreateAccessor(attributes.WEIGHTS_0, out BufferAccessor weights)) b.Add(VertexBuffer.WeightKey, weights); - if (storage.TryCreateAccessor(attributes.JOINTS_0, out BufferAccessor joints)) b.Add(VertexBuffer.JointKey, joints); - - return b; - } - - public static VertexBuffer FromGltf(this gltfMorphTarget target, Vrm10Storage storage) - { - var b = new VertexBuffer(); - storage.CreateBufferAccessorAndAdd(target.POSITION, b, VertexBuffer.PositionKey); - storage.CreateBufferAccessorAndAdd(target.NORMAL, b, VertexBuffer.NormalKey); - storage.CreateBufferAccessorAndAdd(target.TANGENT, b, VertexBuffer.TangentKey); - return b; - } - - public static bool HasSameVertexBuffer(this glTFPrimitives lhs, glTFPrimitives rhs) - { - if (lhs.attributes.POSITION != rhs.attributes.POSITION) return false; - if (lhs.attributes.NORMAL != rhs.attributes.NORMAL) return false; - if (lhs.attributes.TEXCOORD_0 != rhs.attributes.TEXCOORD_0) return false; - if (lhs.attributes.TEXCOORD_1 != rhs.attributes.TEXCOORD_1) return false; - if (lhs.attributes.COLOR_0 != rhs.attributes.COLOR_0) return false; - if (lhs.attributes.WEIGHTS_0 != rhs.attributes.WEIGHTS_0) return false; - if (lhs.attributes.JOINTS_0 != rhs.attributes.JOINTS_0) return false; - return true; - } - - public static bool AllPrimitivesHasSameVertexBuffer(this glTFMesh m) - { - if (m.primitives.Count <= 1) - { - return true; - } - - var first = m.primitives[0]; - for (int i = 1; i < m.primitives.Count; ++i) - { - if (!first.HasSameVertexBuffer(m.primitives[i])) - { - return false; - } - } - - return true; - } - - public static MeshGroup FromGltf(this glTFMesh x, Vrm10Storage storage) - { - var group = new MeshGroup(x.name); - - if (x.primitives.Count == 1) - { - var primitive = x.primitives[0]; - var mesh = primitive.FromGltf(storage, x); - var materialIndex = primitive.material; - - mesh.Submeshes.Add( - new Submesh(0, mesh.IndexBuffer.Count, materialIndex)); - - group.Meshes.Add(mesh); - } - else if (!x.AllPrimitivesHasSameVertexBuffer()) - { - int offset = 0; - foreach (var primitive in x.primitives) - { - var mesh = primitive.FromGltf(storage, x); - var materialIndex = primitive.material; - - mesh.Submeshes.Add( - new Submesh(offset, mesh.IndexBuffer.Count, materialIndex)); - offset += mesh.IndexBuffer.Count; - - group.Meshes.Add(mesh); - } - } - else - { - // for VRM - - var mesh = x.SharedBufferFromGltf(storage); - int offset = 0; - foreach (var primitive in x.primitives) - { - var materialIndex = primitive.material; - var count = storage.Gltf.accessors[primitive.indices].count; - mesh.Submeshes.Add( - new Submesh(offset, count, materialIndex)); - offset += count; - } - - group.Meshes.Add(mesh); - } - - return group; - } - - static void Vec3MinMax(ArraySegment bytes, glTFAccessor accessor) - { - var positions = SpanLike.Wrap(bytes); - var min = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); - var max = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); - foreach (var p in positions) - { - min = Vector3.Min(min, p); - max = Vector3.Max(max, p); - } - accessor.min = min.ToFloat3(); - accessor.max = max.ToFloat3(); - } - - static int ExportIndices(Vrm10Storage storage, BufferAccessor x, int offset, int count, ExportArgs option) - { - if (x.Count <= ushort.MaxValue) - { - if (x.ComponentType == AccessorValueType.UNSIGNED_INT) - { - // ensure ushort - var src = x.GetSpan().Slice(offset, count); - var bytes = new byte[src.Length * 2]; - var dst = SpanLike.Wrap(new ArraySegment(bytes)); - for (int i = 0; i < src.Length; ++i) - { - dst[i] = (ushort)src[i]; - } - var accessor = new BufferAccessor(new ArraySegment(bytes), AccessorValueType.UNSIGNED_SHORT, AccessorVectorType.SCALAR, count); - return accessor.AddAccessorTo(storage, 0, option.sparse, null, 0, count); - } - else - { - return x.AddAccessorTo(storage, 0, option.sparse, null, offset, count); - } - } - else - { - return x.AddAccessorTo(storage, 0, option.sparse, null, offset, count); - } - } - - static void ExportMesh(this Mesh mesh, List materials, Vrm10Storage storage, glTFMesh gltfMesh, ExportArgs option) - { - // - // primitive share vertex buffer - // - var attributeAccessorIndexMap = mesh.VertexBuffer - .ToDictionary( - kv => kv.Key, - kv => kv.Value.AddAccessorTo( - storage, 0, option.sparse, - kv.Key == VertexBuffer.PositionKey ? (Action, glTFAccessor>)Vec3MinMax : null - ) - ); - - List> morphTargetAccessorIndexMapList = null; - if (mesh.MorphTargets.Any()) - { - morphTargetAccessorIndexMapList = new List>(); - foreach (var morphTarget in mesh.MorphTargets) - { - var dict = new Dictionary(); - - foreach (var kv in morphTarget.VertexBuffer) - { - if (option.removeTangent && kv.Key == VertexBuffer.TangentKey) - { - // remove tangent - continue; - } - if (option.removeMorphNormal && kv.Key == VertexBuffer.NormalKey) - { - // normal normal - continue; - } - if (kv.Value.Count != mesh.VertexBuffer.Count) - { - throw new Exception("inavlid data"); - } - var accessorIndex = kv.Value.AddAccessorTo(storage, 0, - option.sparse, - kv.Key == VertexBuffer.PositionKey ? (Action, glTFAccessor>)Vec3MinMax : null); - dict.Add(kv.Key, accessorIndex); - } - - morphTargetAccessorIndexMapList.Add(dict); - } - } - - var drawCountOffset = 0; - foreach (var y in mesh.Submeshes) - { - // index - // slide index buffer accessor - var indicesAccessorIndex = ExportIndices(storage, mesh.IndexBuffer, drawCountOffset, y.DrawCount, option); - drawCountOffset += y.DrawCount; - - var prim = new glTFPrimitives - { - mode = (int)mesh.Topology, - material = y.Material, - indices = indicesAccessorIndex, - attributes = new glTFAttributes(), - }; - gltfMesh.primitives.Add(prim); - - // attribute - foreach (var kv in mesh.VertexBuffer) - { - var attributeAccessorIndex = attributeAccessorIndexMap[kv.Key]; - - switch (kv.Key) - { - case VertexBuffer.PositionKey: prim.attributes.POSITION = attributeAccessorIndex; break; - case VertexBuffer.NormalKey: prim.attributes.NORMAL = attributeAccessorIndex; break; - case VertexBuffer.ColorKey: prim.attributes.COLOR_0 = attributeAccessorIndex; break; - case VertexBuffer.TexCoordKey: prim.attributes.TEXCOORD_0 = attributeAccessorIndex; break; - case VertexBuffer.TexCoordKey2: prim.attributes.TEXCOORD_1 = attributeAccessorIndex; break; - case VertexBuffer.JointKey: prim.attributes.JOINTS_0 = attributeAccessorIndex; break; - case VertexBuffer.WeightKey: prim.attributes.WEIGHTS_0 = attributeAccessorIndex; break; - } - } - - // morph target - if (mesh.MorphTargets.Any()) - { - foreach (var (t, accessorIndexMap) in - Enumerable.Zip(mesh.MorphTargets, morphTargetAccessorIndexMapList, (t, v) => (t, v))) - { - var target = new gltfMorphTarget(); - prim.targets.Add(target); - - foreach (var kv in t.VertexBuffer) - { - if (!accessorIndexMap.TryGetValue(kv.Key, out int targetAccessorIndex)) - { - continue; - } - switch (kv.Key) - { - case VertexBuffer.PositionKey: - target.POSITION = targetAccessorIndex; - break; - case VertexBuffer.NormalKey: - target.NORMAL = targetAccessorIndex; - break; - case VertexBuffer.TangentKey: - target.TANGENT = targetAccessorIndex; - break; - - default: - throw new NotImplementedException(); - } - } - } - - } - } - - // target name - if (mesh.MorphTargets.Any()) - { - gltf_mesh_extras_targetNames.Serialize(gltfMesh, mesh.MorphTargets.Select(z => z.Name)); - } - } - - public static glTFMesh ExportMeshGroup(this MeshGroup src, List materials, Vrm10Storage storage, ExportArgs option) - { - var mesh = new glTFMesh - { - name = src.Name - }; - - foreach (var x in src.Meshes) - { - // MeshとSubmeshがGltfのPrimitiveに相当する? - x.ExportMesh(materials, storage, mesh, option); - } - - return mesh; - } - } -} \ No newline at end of file diff --git a/Assets/VRM10/Runtime/IO/Model.meta b/Assets/VRM10/Runtime/IO/Model.meta new file mode 100644 index 000000000..e91cfb000 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Model.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 18a0f7c989f911547aa4b75abb583b4c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/MeshLoader.cs b/Assets/VRM10/Runtime/IO/Model/MeshImporter.cs similarity index 88% rename from Assets/VRM10/Runtime/IO/MeshLoader.cs rename to Assets/VRM10/Runtime/IO/Model/MeshImporter.cs index d199dd2f8..6d073c3cc 100644 --- a/Assets/VRM10/Runtime/IO/MeshLoader.cs +++ b/Assets/VRM10/Runtime/IO/Model/MeshImporter.cs @@ -1,12 +1,17 @@ using System; using UnityEngine; -using UnityEngine.Rendering; namespace UniVRM10 { - public static class MeshLoader + public static class MeshImporter { - public static void LoadMesh(this Mesh mesh, VrmLib.Mesh src, VrmLib.Skin skin = null) + /// + /// VrmLib.Mesh => UnityEngine.Mesh + /// + /// + /// + /// + public static void LoadSharedMesh(UnityEngine.Mesh mesh, VrmLib.Mesh src, VrmLib.Skin skin = null) { mesh.vertices = src.VertexBuffer.Positions.GetSpan().ToArray(); mesh.normals = src.VertexBuffer.Normals?.GetSpan().ToArray(); diff --git a/Assets/VRM10/Runtime/IO/MeshAdapter.cs.meta b/Assets/VRM10/Runtime/IO/Model/MeshImporter.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/IO/MeshAdapter.cs.meta rename to Assets/VRM10/Runtime/IO/Model/MeshImporter.cs.meta index 7a639894c..c771646a3 100644 --- a/Assets/VRM10/Runtime/IO/MeshAdapter.cs.meta +++ b/Assets/VRM10/Runtime/IO/Model/MeshImporter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 573f68f30d3f14a4cb8181b07981c6e0 +guid: 98874f743a5ae754eb8382f3991a5646 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/IO/Model/MeshReader.cs b/Assets/VRM10/Runtime/IO/Model/MeshReader.cs new file mode 100644 index 000000000..757f57146 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Model/MeshReader.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UniGLTF; +using VrmLib; + +namespace UniVRM10 +{ + /// + /// GLTF -> VrmLib.MeshGroup + /// + public static class MeshReader + { + /// + /// VertexBufferはひとつでIndexBufferの参照が異なる + /// + /// VertexBuffer + /// +----------------------------------+ + /// | | + /// +----------------------------------+ + /// A A A + /// | | | + /// +---------+--------+--------+ + /// | submesh0|submesh1|submesh2| + /// +---------+--------+--------+ + /// IndexBuffer + /// + static Mesh SharedBufferFromGltf(this glTFMesh x, Vrm10Storage storage) + { + // 先頭を使う + return FromGltf(storage, x, x.primitives[0], true); + } + + /// + /// IndexBuffer毎に異なるVertexBufferを参照する + /// + /// VertexBuffer + /// +--------+ +--------+ +--------+ + /// |0 | |1 | |2 | + /// +--------+ +--------+ +--------+ + /// A A A + /// | | | + /// +---------+--------+--------+ + /// | submesh0|submesh1|submesh2| + /// +---------+--------+--------+ + /// IndexBuffer + /// + static Mesh FromGltf(this glTFPrimitives primitive, Vrm10Storage storage, glTFMesh x) + { + return FromGltf(storage, x, primitive, false); + } + + static Mesh FromGltf(Vrm10Storage storage, glTFMesh x, glTFPrimitives primitive, bool isShared) + { + var mesh = new Mesh((TopologyType)primitive.mode) + { + VertexBuffer = primitive.attributes.FromGltf(storage) + }; + + if (isShared) + { + // create joined index buffer + mesh.IndexBuffer = storage.CreateAccessor(x.primitives.Select(y => y.indices).ToArray()); + } + else + { + mesh.IndexBuffer = storage.CreateAccessor(primitive.indices); + } + + { + gltf_mesh_extras_targetNames.TryGet(x, out List targetNames); + + for (int i = 0; i < primitive.targets.Count; ++i) + { + var gltfTarget = primitive.targets[i]; + + string targetName = null; + { + targetName = targetNames[i]; + } + var target = new MorphTarget(targetName) + { + VertexBuffer = gltfTarget.FromGltf(storage) + }; + + // validate count + foreach (var kv in target.VertexBuffer) + { + if (kv.Value.Count != mesh.VertexBuffer.Count) + { + throw new Exception(); + } + } + + mesh.MorphTargets.Add(target); + } + } + + return mesh; + } + + static VertexBuffer FromGltf(this glTFAttributes attributes, + Vrm10Storage storage) + { + var b = new VertexBuffer(); + + if (storage.TryCreateAccessor(attributes.POSITION, out BufferAccessor position)) + { + b.Add(VertexBuffer.PositionKey, position); + } + else + { + // position required + throw new Exception(); + } + + if (storage.TryCreateAccessor(attributes.NORMAL, out BufferAccessor normal)) b.Add(VertexBuffer.NormalKey, normal); + if (storage.TryCreateAccessor(attributes.COLOR_0, out BufferAccessor color)) b.Add(VertexBuffer.ColorKey, color); + if (storage.TryCreateAccessor(attributes.TEXCOORD_0, out BufferAccessor tex0)) b.Add(VertexBuffer.TexCoordKey, tex0); + if (storage.TryCreateAccessor(attributes.TEXCOORD_1, out BufferAccessor tex1)) b.Add(VertexBuffer.TexCoordKey2, tex1); + // if(storage.TryCreateAccessor(attributes.TANGENT, out BufferAccessor tangent))b.Add(VertexBuffer.TangentKey, tangent); + if (storage.TryCreateAccessor(attributes.WEIGHTS_0, out BufferAccessor weights)) b.Add(VertexBuffer.WeightKey, weights); + if (storage.TryCreateAccessor(attributes.JOINTS_0, out BufferAccessor joints)) b.Add(VertexBuffer.JointKey, joints); + + return b; + } + + static VertexBuffer FromGltf(this gltfMorphTarget target, Vrm10Storage storage) + { + var b = new VertexBuffer(); + storage.CreateBufferAccessorAndAdd(target.POSITION, b, VertexBuffer.PositionKey); + storage.CreateBufferAccessorAndAdd(target.NORMAL, b, VertexBuffer.NormalKey); + storage.CreateBufferAccessorAndAdd(target.TANGENT, b, VertexBuffer.TangentKey); + return b; + } + + static bool HasSameVertexBuffer(this glTFPrimitives lhs, glTFPrimitives rhs) + { + if (lhs.attributes.POSITION != rhs.attributes.POSITION) return false; + if (lhs.attributes.NORMAL != rhs.attributes.NORMAL) return false; + if (lhs.attributes.TEXCOORD_0 != rhs.attributes.TEXCOORD_0) return false; + if (lhs.attributes.TEXCOORD_1 != rhs.attributes.TEXCOORD_1) return false; + if (lhs.attributes.COLOR_0 != rhs.attributes.COLOR_0) return false; + if (lhs.attributes.WEIGHTS_0 != rhs.attributes.WEIGHTS_0) return false; + if (lhs.attributes.JOINTS_0 != rhs.attributes.JOINTS_0) return false; + return true; + } + + static bool AllPrimitivesHasSameVertexBuffer(this glTFMesh m) + { + if (m.primitives.Count <= 1) + { + return true; + } + + var first = m.primitives[0]; + for (int i = 1; i < m.primitives.Count; ++i) + { + if (!first.HasSameVertexBuffer(m.primitives[i])) + { + return false; + } + } + + return true; + } + + public static MeshGroup FromGltf(this glTFMesh x, Vrm10Storage storage) + { + var group = new MeshGroup(x.name); + + if (x.primitives.Count == 1) + { + var primitive = x.primitives[0]; + var mesh = primitive.FromGltf(storage, x); + var materialIndex = primitive.material; + + mesh.Submeshes.Add( + new Submesh(0, mesh.IndexBuffer.Count, materialIndex)); + + group.Meshes.Add(mesh); + } + else if (!x.AllPrimitivesHasSameVertexBuffer()) + { + int offset = 0; + foreach (var primitive in x.primitives) + { + var mesh = primitive.FromGltf(storage, x); + var materialIndex = primitive.material; + + mesh.Submeshes.Add( + new Submesh(offset, mesh.IndexBuffer.Count, materialIndex)); + offset += mesh.IndexBuffer.Count; + + group.Meshes.Add(mesh); + } + } + else + { + // + // obsolete + // + // for VRM + + var mesh = x.SharedBufferFromGltf(storage); + int offset = 0; + foreach (var primitive in x.primitives) + { + var materialIndex = primitive.material; + var count = storage.Gltf.accessors[primitive.indices].count; + mesh.Submeshes.Add( + new Submesh(offset, count, materialIndex)); + offset += count; + } + + group.Meshes.Add(mesh); + } + + return group; + } + } +} diff --git a/Assets/VRM10/Runtime/IO/ComponentBuilder.cs.meta b/Assets/VRM10/Runtime/IO/Model/MeshReader.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/IO/ComponentBuilder.cs.meta rename to Assets/VRM10/Runtime/IO/Model/MeshReader.cs.meta index 95f8dff4e..192545061 100644 --- a/Assets/VRM10/Runtime/IO/ComponentBuilder.cs.meta +++ b/Assets/VRM10/Runtime/IO/Model/MeshReader.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a6cc4e6978a4fdf40999cc13aaa472fe +guid: 2f4647a633dfc844eb1b8e7563addba2 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs b/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs new file mode 100644 index 000000000..8349e9e41 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using UniGLTF; +using VrmLib; + +namespace UniVRM10 +{ + /// + /// VrmLib.MeshGroup => GLTF + /// + public static class MeshWriter + { + static void Vec3MinMax(ArraySegment bytes, glTFAccessor accessor) + { + var positions = SpanLike.Wrap(bytes); + var min = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); + var max = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); + foreach (var p in positions) + { + min = Vector3.Min(min, p); + max = Vector3.Max(max, p); + } + accessor.min = min.ToFloat3(); + accessor.max = max.ToFloat3(); + } + + static int ExportIndices(Vrm10Storage storage, BufferAccessor x, int offset, int count, ExportArgs option) + { + if (x.Count <= ushort.MaxValue) + { + if (x.ComponentType == AccessorValueType.UNSIGNED_INT) + { + // ensure ushort + var src = x.GetSpan().Slice(offset, count); + var bytes = new byte[src.Length * 2]; + var dst = SpanLike.Wrap(new ArraySegment(bytes)); + for (int i = 0; i < src.Length; ++i) + { + dst[i] = (ushort)src[i]; + } + var accessor = new BufferAccessor(new ArraySegment(bytes), AccessorValueType.UNSIGNED_SHORT, AccessorVectorType.SCALAR, count); + return accessor.AddAccessorTo(storage, 0, option.sparse, null, 0, count); + } + else + { + return x.AddAccessorTo(storage, 0, option.sparse, null, offset, count); + } + } + else + { + return x.AddAccessorTo(storage, 0, option.sparse, null, offset, count); + } + } + + static void ExportMesh(this VrmLib.Mesh mesh, List materials, Vrm10Storage storage, glTFMesh gltfMesh, ExportArgs option) + { + // + // primitive share vertex buffer + // + var attributeAccessorIndexMap = mesh.VertexBuffer + .ToDictionary( + kv => kv.Key, + kv => kv.Value.AddAccessorTo( + storage, 0, option.sparse, + kv.Key == VertexBuffer.PositionKey ? (Action, glTFAccessor>)Vec3MinMax : null + ) + ); + + List> morphTargetAccessorIndexMapList = null; + if (mesh.MorphTargets.Any()) + { + morphTargetAccessorIndexMapList = new List>(); + foreach (var morphTarget in mesh.MorphTargets) + { + var dict = new Dictionary(); + + foreach (var kv in morphTarget.VertexBuffer) + { + if (option.removeTangent && kv.Key == VertexBuffer.TangentKey) + { + // remove tangent + continue; + } + if (option.removeMorphNormal && kv.Key == VertexBuffer.NormalKey) + { + // normal normal + continue; + } + if (kv.Value.Count != mesh.VertexBuffer.Count) + { + throw new Exception("inavlid data"); + } + var accessorIndex = kv.Value.AddAccessorTo(storage, 0, + option.sparse, + kv.Key == VertexBuffer.PositionKey ? (Action, glTFAccessor>)Vec3MinMax : null); + dict.Add(kv.Key, accessorIndex); + } + + morphTargetAccessorIndexMapList.Add(dict); + } + } + + var drawCountOffset = 0; + foreach (var y in mesh.Submeshes) + { + // index + // slide index buffer accessor + var indicesAccessorIndex = ExportIndices(storage, mesh.IndexBuffer, drawCountOffset, y.DrawCount, option); + drawCountOffset += y.DrawCount; + + var prim = new glTFPrimitives + { + mode = (int)mesh.Topology, + material = y.Material, + indices = indicesAccessorIndex, + attributes = new glTFAttributes(), + }; + gltfMesh.primitives.Add(prim); + + // attribute + foreach (var kv in mesh.VertexBuffer) + { + var attributeAccessorIndex = attributeAccessorIndexMap[kv.Key]; + + switch (kv.Key) + { + case VertexBuffer.PositionKey: prim.attributes.POSITION = attributeAccessorIndex; break; + case VertexBuffer.NormalKey: prim.attributes.NORMAL = attributeAccessorIndex; break; + case VertexBuffer.ColorKey: prim.attributes.COLOR_0 = attributeAccessorIndex; break; + case VertexBuffer.TexCoordKey: prim.attributes.TEXCOORD_0 = attributeAccessorIndex; break; + case VertexBuffer.TexCoordKey2: prim.attributes.TEXCOORD_1 = attributeAccessorIndex; break; + case VertexBuffer.JointKey: prim.attributes.JOINTS_0 = attributeAccessorIndex; break; + case VertexBuffer.WeightKey: prim.attributes.WEIGHTS_0 = attributeAccessorIndex; break; + } + } + + // morph target + if (mesh.MorphTargets.Any()) + { + foreach (var (t, accessorIndexMap) in + Enumerable.Zip(mesh.MorphTargets, morphTargetAccessorIndexMapList, (t, v) => (t, v))) + { + var target = new gltfMorphTarget(); + prim.targets.Add(target); + + foreach (var kv in t.VertexBuffer) + { + if (!accessorIndexMap.TryGetValue(kv.Key, out int targetAccessorIndex)) + { + continue; + } + switch (kv.Key) + { + case VertexBuffer.PositionKey: + target.POSITION = targetAccessorIndex; + break; + case VertexBuffer.NormalKey: + target.NORMAL = targetAccessorIndex; + break; + case VertexBuffer.TangentKey: + target.TANGENT = targetAccessorIndex; + break; + + default: + throw new NotImplementedException(); + } + } + } + + } + } + + // target name + if (mesh.MorphTargets.Any()) + { + gltf_mesh_extras_targetNames.Serialize(gltfMesh, mesh.MorphTargets.Select(z => z.Name)); + } + } + + public static glTFMesh ExportMeshGroup(this MeshGroup src, List materials, Vrm10Storage storage, ExportArgs option) + { + var mesh = new glTFMesh + { + name = src.Name + }; + + foreach (var x in src.Meshes) + { + // MeshとSubmeshがGltfのPrimitiveに相当する? + x.ExportMesh(materials, storage, mesh, option); + } + + return mesh; + } + } +} diff --git a/Assets/VRM10/Runtime/IO/MeshLoader.cs.meta b/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/IO/MeshLoader.cs.meta rename to Assets/VRM10/Runtime/IO/Model/MeshWriter.cs.meta index 808a8fdc7..7cec628aa 100644 --- a/Assets/VRM10/Runtime/IO/MeshLoader.cs.meta +++ b/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d80d88b180871234ea03afcc24e118da +guid: f71759cba771a95449d96df3fa37b115 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/IO/RuntimeVrmConverter.cs b/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs similarity index 97% rename from Assets/VRM10/Runtime/IO/RuntimeVrmConverter.cs rename to Assets/VRM10/Runtime/IO/Model/ModelExporter.cs index afe1b3369..c104874f2 100644 --- a/Assets/VRM10/Runtime/IO/RuntimeVrmConverter.cs +++ b/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs @@ -8,7 +8,10 @@ using VrmLib; namespace UniVRM10 { - public class RuntimeVrmConverter + /// + /// UnityEngine.GameObject hierarchy => GLTF.Nodes, GLTF.Meshes, GLTF.Skins + /// + public class ModelExporter { public VrmLib.Model Model; @@ -16,15 +19,16 @@ namespace UniVRM10 public List Materials = new List(); public Dictionary Meshes = new Dictionary(); - #region Export 1.0 /// - /// metaObject が null のときは、root から取得する + /// GameObject to VrmLib.Model /// + /// + /// public VrmLib.Model ToModelFrom10(GameObject root) { Model = new VrmLib.Model(VrmLib.Coordinates.Unity); - ToGlbModel(root); + Export(root); // humanoid { @@ -48,7 +52,7 @@ namespace UniVRM10 return Model; } - public VrmLib.Model ToGlbModel(GameObject root) + VrmLib.Model Export(GameObject root) { if (Model == null) { @@ -123,9 +127,6 @@ namespace UniVRM10 return Model; } - #endregion - - private static void CreateNodes( Transform parentTransform, diff --git a/Assets/VRM10/Runtime/IO/DictionaryExtensions.cs.meta b/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/IO/DictionaryExtensions.cs.meta rename to Assets/VRM10/Runtime/IO/Model/ModelExporter.cs.meta index 05d8b5981..56f9b9e26 100644 --- a/Assets/VRM10/Runtime/IO/DictionaryExtensions.cs.meta +++ b/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 936824d3022642f40a65a003e0ee3b83 +guid: 096d30ddf9b2aee4f96746f05610d75f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/IO/ModelLoader.cs b/Assets/VRM10/Runtime/IO/Model/ModelReader.cs similarity index 82% rename from Assets/VRM10/Runtime/IO/ModelLoader.cs rename to Assets/VRM10/Runtime/IO/Model/ModelReader.cs index 0c283ed05..876c3c855 100644 --- a/Assets/VRM10/Runtime/IO/ModelLoader.cs +++ b/Assets/VRM10/Runtime/IO/Model/ModelReader.cs @@ -1,12 +1,15 @@ -using System; +using System.IO; using System.Linq; using VrmLib; namespace UniVRM10 { - public static class ModelLoader + /// + /// GLTF => VrmLib.Model + /// + public static class ModelReader { - public static Model Load(Vrm10Storage storage, string rootName) + static Model Load(Vrm10Storage storage, string rootName) { if (storage == null) { @@ -70,5 +73,13 @@ namespace UniVRM10 return model; } + + public static Model Read(UniGLTF.GltfParser parser) + { + var storage = new Vrm10Storage(parser); + var model = Load(storage, Path.GetFileName(parser.TargetPath)); + model.ConvertCoordinate(Coordinates.Unity); + return model; + } } } diff --git a/Assets/VRM10/Runtime/IO/Model/ModelReader.cs.meta b/Assets/VRM10/Runtime/IO/Model/ModelReader.cs.meta new file mode 100644 index 000000000..f9a24df05 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Model/ModelReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb219f8797f990649a7531dbb96d3305 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/ModelLoader.cs.meta b/Assets/VRM10/Runtime/IO/ModelLoader.cs.meta deleted file mode 100644 index 9930454b6..000000000 --- a/Assets/VRM10/Runtime/IO/ModelLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 42576b7471f4a4e4fb25c1815a92f44b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/RuntimeUnityBuilder.cs.meta b/Assets/VRM10/Runtime/IO/RuntimeUnityBuilder.cs.meta deleted file mode 100644 index be6f19107..000000000 --- a/Assets/VRM10/Runtime/IO/RuntimeUnityBuilder.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 962f584a4519d62419f01b8151f99169 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/RuntimeVrmConverter.cs.meta b/Assets/VRM10/Runtime/IO/RuntimeVrmConverter.cs.meta deleted file mode 100644 index a49ea9a83..000000000 --- a/Assets/VRM10/Runtime/IO/RuntimeVrmConverter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6b619b24f8ac1494290458193ebca6aa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index 8b308a8da..05b1526fb 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -128,7 +128,7 @@ namespace UniVRM10 return new float[] { -v.x, v.y, v.z }; } - public void Export(GameObject root, Model model, RuntimeVrmConverter converter, ExportArgs option, Func getTextureBytes, VRM10MetaObject metaObject = null) + public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, Func getTextureBytes, VRM10MetaObject metaObject = null) { ExportAsset(model); @@ -211,7 +211,7 @@ namespace UniVRM10 /// (UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone springBone, - int? thumbnailIndex) ExportVrm(GameObject root, Model model, RuntimeVrmConverter converter, VRM10MetaObject meta) + int? thumbnailIndex) ExportVrm(GameObject root, Model model, ModelExporter converter, VRM10MetaObject meta) { var vrmController = root?.GetComponent(); @@ -307,7 +307,7 @@ namespace UniVRM10 return joint; } - UniGLTF.Extensions.VRMC_springBone.VRMC_springBone ExportSpringBone(VRM10Controller vrmController, Model model, RuntimeVrmConverter converter) + UniGLTF.Extensions.VRMC_springBone.VRMC_springBone ExportSpringBone(VRM10Controller vrmController, Model model, ModelExporter converter) { var springBone = new UniGLTF.Extensions.VRMC_springBone.VRMC_springBone { @@ -353,7 +353,7 @@ namespace UniVRM10 return springBone; } - void ExportConstraints(VRM10Controller vrmController, Model model, RuntimeVrmConverter converter) + void ExportConstraints(VRM10Controller vrmController, Model model, ModelExporter converter) { var constraints = vrmController.GetComponentsInChildren(); foreach (var constraint in constraints) @@ -395,7 +395,7 @@ namespace UniVRM10 }; } - static UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint ExportPostionConstraint(VRM10PositionConstraint c, Model model, RuntimeVrmConverter converter) + static UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint ExportPostionConstraint(VRM10PositionConstraint c, Model model, ModelExporter converter) { return new UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint { @@ -413,7 +413,7 @@ namespace UniVRM10 }; } - static UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint ExportRotationConstraint(VRM10RotationConstraint c, Model model, RuntimeVrmConverter converter) + static UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint ExportRotationConstraint(VRM10RotationConstraint c, Model model, ModelExporter converter) { return new UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint { @@ -431,7 +431,7 @@ namespace UniVRM10 }; } - static UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint ExportAimConstraint(VRM10AimConstraint c, Model model, RuntimeVrmConverter converter) + static UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint ExportAimConstraint(VRM10AimConstraint c, Model model, ModelExporter converter) { return new UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint { @@ -457,7 +457,7 @@ namespace UniVRM10 }; } - void ExportFirstPerson(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10Controller vrmController, Model model, RuntimeVrmConverter converter) + void ExportFirstPerson(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10Controller vrmController, Model model, ModelExporter converter) { if (vrmController?.FirstPerson == null) { @@ -540,7 +540,7 @@ namespace UniVRM10 }; } - void ExportExpression(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10Controller vrmController, Model model, RuntimeVrmConverter converter) + void ExportExpression(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, VRM10Controller vrmController, Model model, ModelExporter converter) { if (vrmController?.Expression?.ExpressionAvatar?.Clips == null) { @@ -779,7 +779,7 @@ namespace UniVRM10 } // ヒエラルキーからジオメトリーを収集 - var converter = new UniVRM10.RuntimeVrmConverter(); + var converter = new UniVRM10.ModelExporter(); var model = converter.ToModelFrom10(go); // 右手系に変換 diff --git a/Assets/VRM10/Runtime/IO/RuntimeUnityBuilder.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs similarity index 98% rename from Assets/VRM10/Runtime/IO/RuntimeUnityBuilder.cs rename to Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 0fc7406cf..3b6bfcef8 100644 --- a/Assets/VRM10/Runtime/IO/RuntimeUnityBuilder.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; using UniGLTF; @@ -12,7 +13,7 @@ namespace UniVRM10 /// /// VrmLib.Model から UnityPrefab を構築する /// - public class RuntimeUnityBuilder : UniGLTF.ImporterContext + public class Vrm10Importer : UniGLTF.ImporterContext { readonly Model m_model; @@ -20,11 +21,15 @@ namespace UniVRM10 IDictionary m_externalMap; - public RuntimeUnityBuilder(UniGLTF.GltfParser parser, IDictionary externalObjectMap = null) - : base(parser, externalObjectMap.Select(kv => (kv.Key.Name, kv.Value))) + public Vrm10Importer(UniGLTF.GltfParser parser, IDictionary externalObjectMap = null) + : base(parser, externalObjectMap?.Select(kv => (kv.Key.Name, kv.Value))) { m_externalMap = externalObjectMap; - m_model = VrmLoader.CreateVrmModel(parser); + if (m_externalMap == null) + { + m_externalMap = new Dictionary(); + } + m_model = ModelReader.Read(parser); // for `VRMC_materials_mtoon` this.GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, Vrm10MaterialImporter.TryCreateParam); @@ -140,7 +145,7 @@ namespace UniVRM10 // submesh 方式 var mesh = new UnityEngine.Mesh(); mesh.name = src.Name; - mesh.LoadMesh(src.Meshes[0], src.Skin); + MeshImporter.LoadSharedMesh(mesh, src.Meshes[0], src.Skin); m_map.Meshes.Add(src, mesh); Meshes.Add(new MeshWithMaterials { diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs.meta b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs.meta new file mode 100644 index 000000000..5d5cacea2 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae61d167cf541b44c8645b3c864390f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/VrmLoader.cs b/Assets/VRM10/Runtime/IO/VrmLoader.cs deleted file mode 100644 index cc59d996d..000000000 --- a/Assets/VRM10/Runtime/IO/VrmLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.IO; -using VrmLib; -using UniGLTF; - -namespace UniVRM10 -{ - /// - /// utility for load VrmLib Model from byte[] - /// - public static class VrmLoader - { - public static Model CreateVrmModel(GltfParser parser) - { - var storage = new Vrm10Storage(parser); - var model = ModelLoader.Load(storage, Path.GetFileName(parser.TargetPath)); - model.ConvertCoordinate(Coordinates.Unity); - return model; - } - } -} diff --git a/Assets/VRM10/Runtime/IO/VrmLoader.cs.meta b/Assets/VRM10/Runtime/IO/VrmLoader.cs.meta deleted file mode 100644 index af911b20b..000000000 --- a/Assets/VRM10/Runtime/IO/VrmLoader.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ef069ccddc286cc4e930ba33447b0094 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Scenes/Sample.cs b/Assets/VRM10/Runtime/Scenes/Sample.cs index b4dc2efec..cb9367c13 100644 --- a/Assets/VRM10/Runtime/Scenes/Sample.cs +++ b/Assets/VRM10/Runtime/Scenes/Sample.cs @@ -16,7 +16,7 @@ public class Sample : MonoBehaviour var parser = new GltfParser(); parser.Parse(path.FullName, bytes); - using (var loader = new RuntimeUnityBuilder(parser)) + using (var loader = new Vrm10Importer(parser)) { loader.Load(); loader.ShowMeshes(); diff --git a/Assets/VRM10/Tests.PlayMode/MaterialTests.cs b/Assets/VRM10/Tests.PlayMode/MaterialTests.cs index da3911619..b29d8fedc 100644 --- a/Assets/VRM10/Tests.PlayMode/MaterialTests.cs +++ b/Assets/VRM10/Tests.PlayMode/MaterialTests.cs @@ -39,7 +39,7 @@ namespace UniVRM10.Test private (GameObject, IReadOnlyList) ToUnity(GltfParser parser) { // Model => Unity - using (var loader = new RuntimeUnityBuilder(parser)) + using (var loader = new Vrm10Importer(parser)) { loader.Load(); loader.DisposeOnGameObjectDestroyed(); @@ -49,7 +49,7 @@ namespace UniVRM10.Test private Model ToVrmModel(GameObject root) { - var exporter = new UniVRM10.RuntimeVrmConverter(); + var exporter = new UniVRM10.ModelExporter(); var model = exporter.ToModelFrom10(root); model.ConvertCoordinate(VrmLib.Coordinates.Vrm1, ignoreVrm: false); diff --git a/Assets/VRM10/Tests/ApiSampleTests.cs b/Assets/VRM10/Tests/ApiSampleTests.cs index fa72a5dd5..336d397d6 100644 --- a/Assets/VRM10/Tests/ApiSampleTests.cs +++ b/Assets/VRM10/Tests/ApiSampleTests.cs @@ -1,9 +1,7 @@ -using System; -using System.IO; +using System.IO; using NUnit.Framework; using UniGLTF; using UnityEngine; -using UnityEngine.TestTools; using VRMShaders; namespace UniVRM10.Test @@ -17,13 +15,13 @@ namespace UniVRM10.Test var parser = new GltfParser(); parser.Parse("migrated", bytes); - var model = UniVRM10.VrmLoader.CreateVrmModel(parser); + var model = ModelReader.Read(parser); return model; } GameObject BuildGameObject(GltfParser parser, bool showMesh) { - using (var loader = new RuntimeUnityBuilder(parser)) + using (var loader = new Vrm10Importer(parser)) { loader.Load(); if (showMesh)