Vrm10Storage を Vrm10ImportData と Vrm10ExportData に分解

This commit is contained in:
ousttrue 2022-02-09 20:36:41 +09:00
parent 0b25d46b36
commit 05928872cd
9 changed files with 144 additions and 139 deletions

View File

@ -30,7 +30,7 @@ namespace UniVRM10
}
public static int AddViewTo(this VrmLib.BufferAccessor self,
Vrm10Storage storage, int bufferIndex,
Vrm10ExportData storage, int bufferIndex,
int offset = 0, int count = 0)
{
var stride = self.Stride;
@ -60,11 +60,11 @@ namespace UniVRM10
}
public static int AddAccessorTo(this VrmLib.BufferAccessor self,
Vrm10Storage storage, int viewIndex,
Vrm10ExportData storage, int viewIndex,
Action<ArraySegment<byte>, glTFAccessor> minMax = null,
int offset = 0, int count = 0)
{
var gltf = storage.Gltf;
var gltf = storage.GLTF;
var accessorIndex = gltf.accessors.Count;
var accessor = self.CreateGltfAccessor(viewIndex, count, offset * self.Stride);
if (minMax != null)
@ -76,7 +76,7 @@ namespace UniVRM10
}
public static int AddAccessorTo(this VrmLib.BufferAccessor self,
Vrm10Storage storage, int bufferIndex,
Vrm10ExportData storage, int bufferIndex,
// GltfBufferTargetType targetType,
bool useSparse,
Action<ArraySegment<byte>, glTFAccessor> minMax = null,
@ -119,7 +119,7 @@ namespace UniVRM10
var sparseIndexView = storage.AppendToBuffer(sparseIndexBin);
var sparseValueView = storage.AppendToBuffer(sparseValueBin);
var accessorIndex = storage.Gltf.accessors.Count;
var accessorIndex = storage.GLTF.accessors.Count;
var accessor = new glTFAccessor
{
componentType = (glComponentType)self.ComponentType,
@ -144,7 +144,7 @@ namespace UniVRM10
{
minMax(sparseValueBin, accessor);
}
storage.Gltf.accessors.Add(accessor);
storage.GLTF.accessors.Add(accessor);
return accessorIndex;
}
}

View File

@ -25,7 +25,7 @@ namespace UniVRM10
/// +---------+--------+--------+
/// IndexBuffer
/// </summary>
static Mesh SharedBufferFromGltf(this glTFMesh x, Vrm10Storage storage)
static Mesh SharedBufferFromGltf(this glTFMesh x, Vrm10ImportData storage)
{
// 先頭を使う
return FromGltf(storage, x, x.primitives[0], true);
@ -45,12 +45,12 @@ namespace UniVRM10
/// +---------+--------+--------+
/// IndexBuffer
/// </summary>
static Mesh FromGltf(this glTFPrimitives primitive, Vrm10Storage storage, glTFMesh x)
static Mesh FromGltf(this glTFPrimitives primitive, Vrm10ImportData storage, glTFMesh x)
{
return FromGltf(storage, x, primitive, false);
}
static Mesh FromGltf(Vrm10Storage storage, glTFMesh x, glTFPrimitives primitive, bool isShared)
static Mesh FromGltf(Vrm10ImportData storage, glTFMesh x, glTFPrimitives primitive, bool isShared)
{
var mesh = new Mesh((TopologyType)primitive.mode)
{
@ -100,7 +100,7 @@ namespace UniVRM10
}
static VertexBuffer FromGltf(this glTFAttributes attributes,
Vrm10Storage storage)
Vrm10ImportData storage)
{
var b = new VertexBuffer();
@ -125,7 +125,7 @@ namespace UniVRM10
return b;
}
static VertexBuffer FromGltf(this gltfMorphTarget target, Vrm10Storage storage)
static VertexBuffer FromGltf(this gltfMorphTarget target, Vrm10ImportData storage)
{
var b = new VertexBuffer();
storage.CreateBufferAccessorAndAdd(target.POSITION, b, VertexBuffer.PositionKey);
@ -165,7 +165,7 @@ namespace UniVRM10
return true;
}
public static MeshGroup FromGltf(this glTFMesh x, Vrm10Storage storage)
public static MeshGroup FromGltf(this glTFMesh x, Vrm10ImportData storage)
{
var group = new MeshGroup(x.name);

View File

@ -26,7 +26,7 @@ namespace UniVRM10
accessor.max = max.ToFloat3();
}
static int ExportIndices(Vrm10Storage storage, BufferAccessor x, int offset, int count, ExportArgs option)
static int ExportIndices(Vrm10ExportData storage, BufferAccessor x, int offset, int count, ExportArgs option)
{
if (x.Count <= ushort.MaxValue)
{

View File

@ -9,7 +9,7 @@ namespace UniVRM10
/// </summary>
public static class ModelReader
{
static Model Load(Vrm10Storage storage, string rootName, Coordinates coords)
static Model Load(Vrm10ImportData storage, string rootName, Coordinates coords)
{
if (storage == null)
{
@ -77,7 +77,7 @@ namespace UniVRM10
public static Model Read(UniGLTF.GltfData data, Coordinates? coords = default)
{
var storage = new Vrm10Storage(data);
var storage = new Vrm10ImportData(data);
var model = Load(storage, Path.GetFileName(data.TargetPath), coords.GetValueOrDefault(Coordinates.Vrm1));
model.ConvertCoordinate(Coordinates.Unity);
return model;

View File

@ -0,0 +1,34 @@
using System;
using UniGLTF;
using UniJSON;
namespace UniVRM10
{
public class Vrm10ExportData : ExportingGltfData
{
public void Reserve(int bytesLength)
{
_buffer.ExtendCapacity(bytesLength);
}
public int AppendToBuffer(ArraySegment<byte> segment)
{
var gltfBufferView = _buffer.Extend(segment);
var viewIndex = GLTF.bufferViews.Count;
GLTF.bufferViews.Add(gltfBufferView);
return viewIndex;
}
public byte[] ToBytes()
{
GLTF.buffers[0].byteLength = _buffer.Bytes.Count;
var f = new JsonFormatter();
UniGLTF.GltfSerializer.Serialize(f, GLTF);
var json = f.GetStoreBytes();
var glb = UniGLTF.Glb.Create(json, _buffer.Bytes);
return glb.ToBytes();
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f9c990b845a5c4b4a84edbf955d8163f
guid: 53bfc0b12550a494e8da90e632e1c456
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -18,7 +18,7 @@ namespace UniVRM10
public const string LICENSE_URL_JA = "https://vrm.dev/licenses/1.0/";
public const string LICENSE_URL_EN = "https://vrm.dev/licenses/1.0/en/";
public readonly Vrm10Storage Storage = new Vrm10Storage();
public readonly Vrm10ExportData Storage = new Vrm10ExportData();
public readonly string VrmExtensionName = "VRMC_vrm";
@ -36,12 +36,12 @@ namespace UniVRM10
throw new ArgumentException(nameof(textureSerializer));
}
Storage.Gltf.extensionsUsed.Add(glTF_KHR_materials_unlit.ExtensionName);
Storage.Gltf.extensionsUsed.Add(glTF_KHR_texture_transform.ExtensionName);
Storage.Gltf.extensionsUsed.Add(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm.ExtensionName);
Storage.Gltf.extensionsUsed.Add(UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon.ExtensionName);
Storage.Gltf.extensionsUsed.Add(UniGLTF.Extensions.VRMC_springBone.VRMC_springBone.ExtensionName);
Storage.Gltf.extensionsUsed.Add(UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint.ExtensionName);
Storage.GLTF.extensionsUsed.Add(glTF_KHR_texture_transform.ExtensionName);
Storage.GLTF.extensionsUsed.Add(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm.ExtensionName);
Storage.GLTF.extensionsUsed.Add(glTF_KHR_materials_unlit.ExtensionName);
Storage.GLTF.extensionsUsed.Add(UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon.ExtensionName);
Storage.GLTF.extensionsUsed.Add(UniGLTF.Extensions.VRMC_springBone.VRMC_springBone.ExtensionName);
Storage.GLTF.extensionsUsed.Add(UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint.ExtensionName);
m_textureSerializer = textureSerializer;
m_textureExporter = new TextureExporter(m_textureSerializer);
@ -70,7 +70,7 @@ namespace UniVRM10
}
}
public static IEnumerable<(glTFNode, glTFSkin)> ExportNodes(List<Node> nodes, List<MeshGroup> groups, Vrm10Storage storage, ExportArgs option)
public static IEnumerable<(glTFNode, glTFSkin)> ExportNodes(List<Node> nodes, List<MeshGroup> groups, Vrm10ExportData storage, ExportArgs option)
{
foreach (var node in nodes)
{
@ -166,36 +166,36 @@ namespace UniVRM10
public void Export(GameObject root, Model model, ModelExporter converter, ExportArgs option, VRM10ObjectMeta vrmMeta = null)
{
Storage.Gltf.asset = ExportAsset(model);
Storage.GLTF.asset = ExportAsset(model);
Storage.Reserve(CalcReserveBytes(model));
foreach (var material in ExportMaterials(model, m_textureExporter, m_settings))
{
Storage.Gltf.materials.Add(material);
Storage.GLTF.materials.Add(material);
}
foreach (var mesh in ExportMeshes(model.MeshGroups, model.Materials, Storage, option))
{
Storage.Gltf.meshes.Add(mesh);
Storage.GLTF.meshes.Add(mesh);
}
foreach (var (node, skin) in ExportNodes(model.Nodes, model.MeshGroups, Storage, option))
{
Storage.Gltf.nodes.Add(node);
Storage.GLTF.nodes.Add(node);
if (skin != null)
{
var skinIndex = Storage.Gltf.skins.Count;
Storage.Gltf.skins.Add(skin);
var skinIndex = Storage.GLTF.skins.Count;
Storage.GLTF.skins.Add(skin);
node.skin = skinIndex;
}
}
Storage.Gltf.scenes.Add(new gltfScene()
Storage.GLTF.scenes.Add(new gltfScene()
{
nodes = model.Root.Children.Select(child => model.Nodes.IndexOfThrow(child)).ToArray()
});
var (vrm, vrmSpringBone, thumbnailTextureIndex) = ExportVrm(root, model, converter, vrmMeta, Storage.Gltf.nodes, m_textureExporter);
var (vrm, vrmSpringBone, thumbnailTextureIndex) = ExportVrm(root, model, converter, vrmMeta, Storage.GLTF.nodes, m_textureExporter);
// Extension で Texture が増える場合があるので最後に呼ぶ
var exportedTextures = m_textureExporter.Export();
@ -207,18 +207,18 @@ namespace UniVRM10
if (thumbnailTextureIndex.HasValue)
{
vrm.Meta.ThumbnailImage = Storage.Gltf.textures[thumbnailTextureIndex.Value].source;
vrm.Meta.ThumbnailImage = Storage.GLTF.textures[thumbnailTextureIndex.Value].source;
}
UniGLTF.Extensions.VRMC_vrm.GltfSerializer.SerializeTo(ref Storage.Gltf.extensions, vrm);
UniGLTF.Extensions.VRMC_vrm.GltfSerializer.SerializeTo(ref Storage.GLTF.extensions, vrm);
if (vrmSpringBone != null)
{
UniGLTF.Extensions.VRMC_springBone.GltfSerializer.SerializeTo(ref Storage.Gltf.extensions, vrmSpringBone);
UniGLTF.Extensions.VRMC_springBone.GltfSerializer.SerializeTo(ref Storage.GLTF.extensions, vrmSpringBone);
}
// Fix Duplicated name
gltfExporter.FixName(Storage.Gltf);
gltfExporter.FixName(Storage.GLTF);
}

View File

@ -1,45 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Numerics;
using UniGLTF;
using UniJSON;
using VrmLib;
using System.Collections.Generic;
namespace UniVRM10
{
public class Vrm10Storage : ExportingGltfData
public class Vrm10ImportData
{
UniGLTF.GltfData m_data;
public UniGLTF.glTF Gltf => m_data.GLTF;
public string AssetVersion => Gltf.asset.version;
public string AssetMinVersion => Gltf.asset.minVersion;
public string AssetGenerator => Gltf.asset.generator;
public string AssetCopyright => Gltf.asset.copyright;
public int NodeCount => Gltf.nodes.Count;
public int TextureCount => Gltf.textures.Count;
public int SkinCount => Gltf.skins.Count;
public int MeshCount => Gltf.meshes.Count;
public UniGLTF.Extensions.VRMC_vrm.VRMC_vrm gltfVrm;
public UniGLTF.Extensions.VRMC_springBone.VRMC_springBone gltfVrmSpringBone;
/// <summary>
/// for export
/// </summary>
public Vrm10Storage()
{
m_data = new GltfData(
string.Empty,
string.Empty,
GLTF,
new List<GlbChunk>(),
default,
new MigrationFlags()
);
}
ArraySegmentByteBuffer _buffer;
/// <summary>
/// for import
/// </summary>
/// <param name="json"></param>
/// <param name="bin"></param>
public Vrm10Storage(UniGLTF.GltfData data)
public Vrm10ImportData(UniGLTF.GltfData data)
{
m_data = data;
@ -58,17 +59,23 @@ namespace UniVRM10
_buffer = new ArraySegmentByteBuffer(new ArraySegment<byte>(data.Bin.ToArray()));
}
public void Reserve(int bytesLength)
public ArraySegment<byte> GetBufferBytes(UniGLTF.glTFBufferView bufferView)
{
_buffer.ExtendCapacity(bytesLength);
if (!bufferView.buffer.TryGetValidIndex(Gltf.buffers.Count, out int bufferViewBufferIndex))
{
throw new Exception();
}
return GetBufferBytes(Gltf.buffers[bufferViewBufferIndex]);
}
public int AppendToBuffer(ArraySegment<byte> segment)
public ArraySegment<byte> GetBufferBytes(UniGLTF.glTFBuffer buffer)
{
var gltfBufferView = _buffer.Extend(segment);
var viewIndex = Gltf.bufferViews.Count;
Gltf.bufferViews.Add(gltfBufferView);
return viewIndex;
int index = Gltf.buffers.IndexOf(buffer);
if (index != 0)
{
throw new NotImplementedException();
}
return _buffer.Bytes;
}
static ArraySegment<byte> RestoreSparseAccessorUInt16<T>(ArraySegment<byte> bytes, int accessorCount, ArraySegment<byte> indicesBytes, ArraySegment<byte> valuesBytes)
@ -129,8 +136,8 @@ namespace UniVRM10
var view = Gltf.bufferViews[bufferViewIndex];
if (view.buffer.TryGetValidIndex(Gltf.buffers.Count, out int bufferIndex))
{
var buffer = _buffer;
var bin = buffer.Bytes;
var buffer = m_data.Bin;
var bin = _buffer.Bytes;
var byteSize = accessor.CalcByteSize();
bytes = bin.Slice(view.byteOffset, view.byteLength).Slice(accessor.byteOffset, byteSize);
}
@ -189,6 +196,33 @@ namespace UniVRM10
}
}
public bool TryCreateAccessor(int accessorIndex, out BufferAccessor ba)
{
if (accessorIndex < 0 || accessorIndex >= Gltf.accessors.Count)
{
ba = default;
return false;
}
var accessor = Gltf.accessors[accessorIndex];
var bytes = GetAccessorBytes(accessorIndex);
var vectorType = EnumUtil.Parse<AccessorVectorType>(accessor.type);
ba = new BufferAccessor(bytes,
(AccessorValueType)accessor.componentType, vectorType, accessor.count);
return true;
}
public BufferAccessor CreateAccessor(int accessorIndex)
{
if (TryCreateAccessor(accessorIndex, out BufferAccessor ba))
{
return ba;
}
else
{
return null;
}
}
/// <summary>
/// submeshのindexが連続した領域に格納されているかを確認する
/// </summary>
@ -321,49 +355,6 @@ namespace UniVRM10
}
}
public BufferAccessor CreateAccessor(int accessorIndex)
{
if (TryCreateAccessor(accessorIndex, out BufferAccessor ba))
{
return ba;
}
else
{
return null;
}
}
public bool TryCreateAccessor(int accessorIndex, out BufferAccessor ba)
{
if (accessorIndex < 0 || accessorIndex >= Gltf.accessors.Count)
{
ba = default;
return false;
}
var accessor = Gltf.accessors[accessorIndex];
var bytes = GetAccessorBytes(accessorIndex);
var vectorType = EnumUtil.Parse<AccessorVectorType>(accessor.type);
ba = new BufferAccessor(bytes,
(AccessorValueType)accessor.componentType, vectorType, accessor.count);
return true;
}
public string AssetVersion => Gltf.asset.version;
public string AssetMinVersion => Gltf.asset.minVersion;
public string AssetGenerator => Gltf.asset.generator;
public string AssetCopyright => Gltf.asset.copyright;
public int NodeCount => Gltf.nodes.Count;
public int TextureCount => Gltf.textures.Count;
public int SkinCount => Gltf.skins.Count;
public int MeshCount => Gltf.meshes.Count;
public Node CreateNode(int index)
{
var x = Gltf.nodes[index];
@ -458,36 +449,5 @@ namespace UniVRM10
return (meshIndex, skinIndex);
}
public ArraySegment<byte> GetBufferBytes(UniGLTF.glTFBufferView bufferView)
{
if (!bufferView.buffer.TryGetValidIndex(Gltf.buffers.Count, out int bufferViewBufferIndex))
{
throw new Exception();
}
return GetBufferBytes(Gltf.buffers[bufferViewBufferIndex]);
}
public ArraySegment<byte> GetBufferBytes(UniGLTF.glTFBuffer buffer)
{
int index = Gltf.buffers.IndexOf(buffer);
if (index != 0)
{
throw new NotImplementedException();
}
return _buffer.Bytes;
}
public byte[] ToBytes()
{
Gltf.buffers[0].byteLength = _buffer.Bytes.Count;
var f = new JsonFormatter();
UniGLTF.GltfSerializer.Serialize(f, Gltf);
var json = f.GetStoreBytes();
var glb = UniGLTF.Glb.Create(json, _buffer.Bytes);
return glb.ToBytes();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a095747b4e9fcf1439a10e2e4913a32d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: