Merge pull request #1343 from ousttrue/fix/data_uri_handling

bufferView の data uri を実装
This commit is contained in:
ousttrue
2021-10-27 20:43:04 +09:00
committed by GitHub
20 changed files with 192 additions and 255 deletions

View File

@@ -114,16 +114,19 @@ namespace UniGLTF
}
else
{
var (json, buffers) = data.ToGltf(path);
// without BOM
var encoding = new System.Text.UTF8Encoding(false);
File.WriteAllText(path, json, encoding);
// write to local folder
var dir = Path.GetDirectoryName(path);
foreach (var b in buffers)
var (json, buffer0) = data.ToGltf(path);
{
var bufferPath = Path.Combine(dir, b.uri);
File.WriteAllBytes(bufferPath, b.GetBytes().ToArray());
// write JSON without BOM
var encoding = new System.Text.UTF8Encoding(false);
File.WriteAllText(path, json, encoding);
}
{
// write to buffer0 local folder
var dir = Path.GetDirectoryName(path);
var bufferPath = Path.Combine(dir, buffer0.uri);
File.WriteAllBytes(bufferPath, data.BinBytes.ToArray());
}
}

View File

@@ -12,10 +12,6 @@ namespace UniGLTF
/// 1. url による相対パス
/// 2. url によるbase64 encoding
/// 3. url がnullのときに bin chunk(buffers[0]) にアクセスする
///
/// TODO:
/// 1. url による相対パス
/// 以外をやめて、呼び出し側で分岐させる。
/// </summary>
/// <param name="url"></param>
/// <returns></returns>

View File

@@ -6,24 +6,6 @@ namespace UniGLTF
[Serializable]
public class glTFBuffer
{
IBytesBuffer m_buffer;
public IBytesBuffer Buffer => m_buffer;
public void OpenStorage(IStorage storage)
{
m_buffer = new ArraySegmentByteBuffer(storage.Get(uri));
}
public glTFBuffer()
{
}
public glTFBuffer(IBytesBuffer storage)
{
m_buffer = storage;
}
public string uri;
[JsonSchema(Required = true, Minimum = 1)]
@@ -33,22 +15,6 @@ namespace UniGLTF
public glTFExtension extensions;
public glTFExtension extras;
public string name;
public glTFBufferView Append<T>(T[] array, glBufferTarget target) where T : struct
{
return Append(new ArraySegment<T>(array), target);
}
public glTFBufferView Append<T>(ArraySegment<T> segment, glBufferTarget target) where T : struct
{
var view = m_buffer.Extend(segment, target);
byteLength = m_buffer.Bytes.Count;
return view;
}
public ArraySegment<Byte> GetBytes()
{
return m_buffer.Bytes;
}
}
[Serializable]

View File

@@ -7,9 +7,13 @@ namespace UniGLTF
{
public class ExportingGltfData
{
readonly glTF _gltf = new glTF();
public glTF GLTF { get; } = new glTF();
public glTF GLTF => _gltf;
protected IBytesBuffer _buffer;
/// <summary>
/// bin chunk
/// </summary>
public ArraySegment<byte> BinBytes => _buffer.Bytes;
public ExportingGltfData(int reserved = default)
{
@@ -17,11 +21,20 @@ namespace UniGLTF
{
reserved = 50 * 1024 * 1024;
}
// glb body と gltf の bin 兼用
_gltf.buffers.Add(new glTFBuffer(new ArrayByteBuffer(new byte[reserved])));
// buffers[0] is export target
GLTF.buffers.Add(new glTFBuffer());
_buffer = new ArrayByteBuffer(new byte[reserved]);
}
#region Buffer management for export
public glTFBufferView ExtendBufferAndGetView<T>(ArraySegment<T> segment, glBufferTarget target) where T : struct
{
var view = _buffer.Extend(segment, target);
GLTF.buffers[0].byteLength = _buffer.Bytes.Count;
return view;
}
public int ExtendBufferAndGetViewIndex<T>(
ArraySegment<T> array,
glBufferTarget target = glBufferTarget.NONE) where T : struct
@@ -30,9 +43,9 @@ namespace UniGLTF
{
return -1;
}
var view = _gltf.buffers[0].Append(array, target);
var viewIndex = _gltf.bufferViews.Count;
_gltf.bufferViews.Add(view);
var view = ExtendBufferAndGetView(array, target);
var viewIndex = GLTF.bufferViews.Count;
GLTF.bufferViews.Add(view);
return viewIndex;
}
@@ -54,10 +67,10 @@ namespace UniGLTF
var viewIndex = ExtendBufferAndGetViewIndex(array, target);
// index buffer's byteStride is unnecessary
_gltf.bufferViews[viewIndex].byteStride = 0;
GLTF.bufferViews[viewIndex].byteStride = 0;
var accessorIndex = _gltf.accessors.Count;
_gltf.accessors.Add(new glTFAccessor
var accessorIndex = GLTF.accessors.Count;
GLTF.accessors.Add(new glTFAccessor
{
bufferView = viewIndex,
byteOffset = 0,
@@ -98,8 +111,8 @@ namespace UniGLTF
return -1;
}
var sparseValuesViewIndex = ExtendBufferAndGetViewIndex(sparseValues, target);
var accessorIndex = _gltf.accessors.Count;
_gltf.accessors.Add(new glTFAccessor
var accessorIndex = GLTF.accessors.Count;
GLTF.accessors.Add(new glTFAccessor
{
byteOffset = 0,
componentType = glTFExtensions.GetComponentType<T>(),
@@ -192,12 +205,12 @@ namespace UniGLTF
public byte[] ToGlbBytes()
{
var f = new JsonFormatter();
GltfSerializer.Serialize(f, _gltf);
GltfSerializer.Serialize(f, GLTF);
// remove unused extenions
var json = f.ToString().ParseAsJson().ToString(" ");
RemoveUnusedExtensions(_gltf, json);
return Glb.Create(json, _gltf.buffers[0].GetBytes()).ToBytes();
RemoveUnusedExtensions(GLTF, json);
return Glb.Create(json, BinBytes).ToBytes();
}
/// <summary>
@@ -205,13 +218,13 @@ namespace UniGLTF
/// </summary>
/// <param name="gltfPath"></param>
/// <returns></returns>
public (string, List<glTFBuffer>) ToGltf(string gltfPath)
public (string, glTFBuffer) ToGltf(string gltfPath)
{
// fix buffer path
if (_gltf.buffers.Count == 1)
if (GLTF.buffers.Count == 1)
{
var withoutExt = Path.GetFileNameWithoutExtension(gltfPath);
_gltf.buffers[0].uri = $"{withoutExt}.bin";
GLTF.buffers[0].uri = $"{withoutExt}.bin";
}
else
{
@@ -219,10 +232,10 @@ namespace UniGLTF
}
var f = new JsonFormatter();
GltfSerializer.Serialize(f, _gltf);
GltfSerializer.Serialize(f, GLTF);
var json = f.ToString().ParseAsJson().ToString(" ");
RemoveUnusedExtensions(_gltf, json);
return (json, _gltf.buffers);
RemoveUnusedExtensions(GLTF, json);
return (json, GLTF.buffers[0]);
}
#endregion
}

View File

@@ -1,31 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace UniGLTF
{
/// <summary>
/// Implement bin chunk access
/// </summary>
public class SimpleStorage : IStorage
{
ArraySegment<Byte> m_bytes;
public SimpleStorage() : this(new ArraySegment<byte>())
{
}
public SimpleStorage(ArraySegment<Byte> bytes)
{
m_bytes = bytes;
}
public ArraySegment<byte> Get(string url)
{
return m_bytes;
}
}
/// <summary>
/// Implement url that represnet relative path
/// </summary>
@@ -40,30 +17,8 @@ namespace UniGLTF
public ArraySegment<byte> Get(string url)
{
var bytes =
(url.FastStartsWith("data:"))
? UriByteBuffer.ReadEmbedded(url)
: File.ReadAllBytes(Path.Combine(m_root, url))
;
var bytes = File.ReadAllBytes(Path.Combine(m_root, url));
return new ArraySegment<byte>(bytes);
}
}
/// <summary>
/// for UnitTest
/// </summary>
public sealed class GltfStorage : IStorage
{
glTF _gltf;
public GltfStorage(glTF gltf)
{
_gltf = gltf;
}
public ArraySegment<byte> Get(string url)
{
return _gltf.buffers[0].GetBytes();
}
}
}

View File

@@ -42,18 +42,34 @@ namespace UniGLTF
/// > This chunk MUST be the second chunk of the Binary glTF asset
/// </summary>
/// <returns></returns>
public ArraySegment<byte> Bin => Chunks[1].Bytes;
/// <summary>
/// URI access
/// </summary>
public IStorage _storage;
public ArraySegment<byte> Bin
{
get
{
if (Chunks == null)
{
return default;
}
if (Chunks.Count < 2)
{
return default;
}
return Chunks[1].Bytes;
}
}
/// <summary>
/// Migration Flags used by ImporterContext
/// </summary>
public MigrationFlags MigrationFlags { get; }
/// <summary>
/// URI access
/// </summary>
IStorage _storage;
Dictionary<string, ArraySegment<byte>> _dataUriCache = new Dictionary<string, ArraySegment<byte>>();
public GltfData(string targetPath, string json, glTF gltf, IReadOnlyList<GlbChunk> chunks, IStorage storage, MigrationFlags migrationFlags)
{
TargetPath = targetPath;
@@ -64,72 +80,114 @@ namespace UniGLTF
MigrationFlags = migrationFlags;
}
public static GltfData CreateFromGltfDataForTest(glTF gltf, ArraySegment<byte> bytes = default)
public static GltfData CreateFromExportForTest(ExportingGltfData data)
{
return CreateFromGltfDataForTest(data.GLTF, data.BinBytes);
}
public static GltfData CreateFromGltfDataForTest(glTF gltf, ArraySegment<byte> bytes)
{
IStorage storage = null;
if (bytes.Array != null)
{
storage = new SimpleStorage(bytes);
}
else
{
storage = new GltfStorage(gltf);
}
return new GltfData(
string.Empty,
string.Empty,
gltf,
new List<GlbChunk>(),
storage,
new List<GlbChunk>
{
new GlbChunk(), // json
GlbChunk.CreateBin(bytes),
},
default,
new MigrationFlags()
);
}
public ArraySegment<Byte> GetBytes(int bufferIndex)
public ArraySegment<Byte> GetBytesFromUri(string uri)
{
// TODO:
var buffer = GLTF.buffers[bufferIndex];
return _storage.Get(buffer.uri);
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentNullException();
}
if (uri.StartsWith("data:", StringComparison.Ordinal))
{
if (_dataUriCache.TryGetValue(uri, out ArraySegment<byte> data))
{
return data;
}
data = new ArraySegment<byte>(UriByteBuffer.ReadEmbedded(uri));
_dataUriCache.Add(uri, data);
return data;
}
else
{
return _storage.Get(uri);
}
}
public ArraySegment<Byte> GetViewBytes(int bufferView)
public ArraySegment<Byte> GetBytesFromBuffer(int bufferIndex)
{
var buffer = GLTF.buffers[bufferIndex];
if (bufferIndex == 0 && string.IsNullOrEmpty(buffer.uri))
{
// https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#glb-stored-buffer
// this buffer is reference bin chunk
if (Bin.Array == null)
{
throw new NullReferenceException();
}
return Bin;
}
else
{
return GetBytesFromUri(buffer.uri);
}
}
public ArraySegment<Byte> GetBytesFromBufferView(int bufferView)
{
var view = GLTF.bufferViews[bufferView];
var segment = GetBytes(view.buffer);
var segment = GetBytesFromBuffer(view.buffer);
return new ArraySegment<byte>(segment.Array, segment.Offset + view.byteOffset, view.byteLength);
}
T[] GetAttrib<T>(int count, int byteOffset, glTFBufferView view) where T : struct
T[] GetTypedFromBufferView<T>(int count, int byteOffset, glTFBufferView view) where T : struct
{
var segment = GetBytes(view.buffer);
var segment = GetBytesFromBuffer(view.buffer);
var attrib = new T[count];
var bytes = new ArraySegment<Byte>(segment.Array, segment.Offset + view.byteOffset + byteOffset, count * view.byteStride);
bytes.MarshalCopyTo(attrib);
return attrib;
}
T[] GetAttrib<T>(glTFAccessor accessor, glTFBufferView view) where T : struct
T[] GetTypedFromAccessor<T>(glTFAccessor accessor, glTFBufferView view) where T : struct
{
return GetAttrib<T>(accessor.count, accessor.byteOffset, view);
return GetTypedFromBufferView<T>(accessor.count, accessor.byteOffset, view);
}
IEnumerable<int> _GetIndices(glTFBufferView view, int count, int byteOffset, glComponentType componentType)
/// <summary>
/// for sparse
/// </summary>
/// <param name="view"></param>
/// <param name="count"></param>
/// <param name="byteOffset"></param>
/// <param name="componentType"></param>
/// <returns></returns>
IEnumerable<int> GetIntIndicesFromView(glTFBufferView view, int count, int byteOffset, glComponentType componentType)
{
switch (componentType)
{
case glComponentType.UNSIGNED_BYTE:
{
return GetAttrib<Byte>(count, byteOffset, view).Select(x => (int)(x));
return GetTypedFromBufferView<Byte>(count, byteOffset, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_SHORT:
{
return GetAttrib<UInt16>(count, byteOffset, view).Select(x => (int)(x));
return GetTypedFromBufferView<UInt16>(count, byteOffset, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_INT:
{
return GetAttrib<UInt32>(count, byteOffset, view).Select(x => (int)(x));
return GetTypedFromBufferView<UInt32>(count, byteOffset, view).Select(x => (int)(x));
}
}
throw new NotImplementedException("GetIndices: unknown componenttype: " + componentType);
@@ -141,7 +199,7 @@ namespace UniGLTF
/// <param name="accessor"></param>
/// <param name="count"></param>
/// <returns></returns>
IEnumerable<int> _GetIndices(glTFAccessor accessor, out int count)
IEnumerable<int> GetIntIndicesFromAccessor(glTFAccessor accessor, out int count)
{
count = accessor.count;
var view = GLTF.bufferViews[accessor.bufferView];
@@ -149,17 +207,17 @@ namespace UniGLTF
{
case glComponentType.UNSIGNED_BYTE:
{
return GetAttrib<Byte>(accessor, view).Select(x => (int)(x));
return GetTypedFromAccessor<Byte>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_SHORT:
{
return GetAttrib<UInt16>(accessor, view).Select(x => (int)(x));
return GetTypedFromAccessor<UInt16>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_INT:
{
return GetAttrib<UInt32>(accessor, view).Select(x => (int)(x));
return GetTypedFromAccessor<UInt32>(accessor, view).Select(x => (int)(x));
}
}
throw new NotImplementedException("GetIndices: unknown componenttype: " + accessor.componentType);
@@ -168,7 +226,7 @@ namespace UniGLTF
public int[] GetIndices(int accessorIndex)
{
int count;
var result = _GetIndices(GLTF.accessors[accessorIndex], out count);
var result = GetIntIndicesFromAccessor(GLTF.accessors[accessorIndex], out count);
var indices = new int[count];
// flip triangles
@@ -192,7 +250,7 @@ namespace UniGLTF
if (vertexAccessor.count <= 0) return new T[] { };
var result = (vertexAccessor.bufferView != -1)
? GetAttrib<T>(vertexAccessor, GLTF.bufferViews[vertexAccessor.bufferView])
? GetTypedFromAccessor<T>(vertexAccessor, GLTF.bufferViews[vertexAccessor.bufferView])
: new T[vertexAccessor.count]
;
@@ -200,8 +258,8 @@ namespace UniGLTF
if (sparse != null && sparse.count > 0)
{
// override sparse values
var indices = _GetIndices(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
var values = GetAttrib<T>(sparse.count, sparse.values.byteOffset, GLTF.bufferViews[sparse.values.bufferView]);
var indices = GetIntIndicesFromView(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
var values = GetTypedFromBufferView<T>(sparse.count, sparse.values.byteOffset, GLTF.bufferViews[sparse.values.bufferView]);
var it = indices.GetEnumerator();
for (int i = 0; i < sparse.count; ++i)
@@ -226,7 +284,7 @@ namespace UniGLTF
{
var attrib = new float[vertexAccessor.count * vertexAccessor.TypeCount];
var view = GLTF.bufferViews[vertexAccessor.bufferView];
var segment = GetBytes(view.buffer);
var segment = GetBytesFromBuffer(view.buffer);
var bytes = new ArraySegment<Byte>(segment.Array, segment.Offset + view.byteOffset + vertexAccessor.byteOffset, vertexAccessor.count * view.byteStride);
bytes.MarshalCopyTo(attrib);
result = attrib;
@@ -240,8 +298,8 @@ namespace UniGLTF
if (sparse != null && sparse.count > 0)
{
// override sparse values
var indices = _GetIndices(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
var values = GetAttrib<float>(sparse.count * vertexAccessor.TypeCount, sparse.values.byteOffset, GLTF.bufferViews[sparse.values.bufferView]);
var indices = GetIntIndicesFromView(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
var values = GetTypedFromBufferView<float>(sparse.count * vertexAccessor.TypeCount, sparse.values.byteOffset, GLTF.bufferViews[sparse.values.bufferView]);
var it = indices.GetEnumerator();
for (int i = 0; i < sparse.count; ++i)
@@ -253,23 +311,23 @@ namespace UniGLTF
return result;
}
public ArraySegment<Byte> GetImageBytes(int imageIndex)
public ArraySegment<Byte> GetBytesFromImage(int imageIndex)
{
var image = GLTF.images[imageIndex];
if (string.IsNullOrEmpty(image.uri))
{
return GetViewBytes(image.bufferView);
return GetBytesFromBufferView(image.bufferView);
}
else
{
return _storage.Get(image.uri);
return GetBytesFromUri(image.uri);
}
}
public ArraySegment<Byte> GetImageBytesFromTextureIndex(int textureIndex)
{
var imageIndex = GLTF.textures[textureIndex].source;
return GetImageBytes(imageIndex);
return GetBytesFromImage(imageIndex);
}
}
}

View File

@@ -35,7 +35,7 @@ namespace UniGLTF
_path,
Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count),
chunks,
new SimpleStorage(chunks[1].Bytes),
default,
new MigrationFlags()
);
}
@@ -92,13 +92,6 @@ namespace UniGLTF
FixNodeName(GLTF);
FixAnimationNameUnique(GLTF);
// parepare byte buffer
//GLTF.baseDir = System.IO.Path.GetDirectoryName(Path);
foreach (var buffer in GLTF.buffers)
{
buffer.OpenStorage(storage);
}
return new GltfData(path, json, GLTF, chunks, storage, migrationFlags);
}

View File

@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
namespace UniGLTF
{
/// <summary>
/// For unit tests.
/// JSON string with storage parser.
/// </summary>
public sealed class JsonWithStorageParser
{
private readonly string _json;
private readonly IStorage _storage;
public JsonWithStorageParser(string json, IStorage storage = null)
{
_json = json;
_storage = storage ?? new SimpleStorage(new ArraySegment<byte>());
}
public GltfData Parse()
{
return GlbLowLevelParser.ParseGltf(
string.Empty,
_json,
new List<GlbChunk>(),
_storage,
new MigrationFlags()
);
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: c103da8b4a2b4050be09e7bfce2769fd
timeCreated: 1624803637

View File

@@ -143,10 +143,10 @@ namespace UniGLTF
UnityEngine.Object.DestroyImmediate(mat);
UnityEngine.Object.DestroyImmediate(root);
var parsed = GltfData.CreateFromGltfDataForTest(gltf);
var parsed = GltfData.CreateFromGltfDataForTest(gltf, data.BinBytes);
// Extract Image to Texture2D
var exportedBytes = parsed.GetViewBytes(exportedImage.bufferView).ToArray();
var exportedBytes = parsed.GetBytesFromBufferView(exportedImage.bufferView).ToArray();
var exportedTexture = new Texture2D(2, 2, TextureFormat.ARGB32, mipChain: false, linear: false);
Assert.IsTrue(exportedTexture.LoadImage(exportedBytes)); // Always true ?
Assert.AreEqual(srcTex.width, exportedTexture.width);

View File

@@ -11,7 +11,6 @@ namespace UniGLTF
var data = new ExportingGltfData();
var gltf = data.GLTF;
gltf.asset.version = "2.0";
gltf.buffers.Add(new glTFBuffer(new ArrayByteBuffer(Array.Empty<byte>())));
gltf.textures.Add(new glTFTexture
{
name = "FooBar",

View File

@@ -137,7 +137,7 @@ namespace UniGLTF
: MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
;
var parsed = GltfData.CreateFromGltfDataForTest(data.GLTF);
var parsed = GltfData.CreateFromGltfDataForTest(data.GLTF, data.BinBytes);
{
var indices = parsed.GetIndices(gltfMesh.primitives[0].indices);
@@ -186,7 +186,7 @@ namespace UniGLTF
: MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
;
var parsed = GltfData.CreateFromGltfDataForTest(data.GLTF);
var parsed = GltfData.CreateFromGltfDataForTest(data.GLTF, data.BinBytes);
{
var indices = parsed.GetIndices(gltfMesh.primitives[0].indices);
Assert.AreEqual(0, indices[0]);

View File

@@ -235,7 +235,7 @@ namespace UniGLTF
string.Empty,
gltf,
new List<GlbChunk>(),
new SimpleStorage(new ArraySegment<byte>()),
default,
new MigrationFlags()
);
}

View File

@@ -115,7 +115,7 @@ namespace UniGLTF
}
// parse
var parsed = new JsonWithStorageParser(json).Parse();
var parsed = GltfData.CreateFromExportForTest(data);
// import
using (var context = new ImporterContext(parsed))
@@ -129,7 +129,8 @@ namespace UniGLTF
{
var initBytes = init == 0 ? null : new byte[init];
var storage = new ArrayByteBuffer(initBytes);
var buffer = new glTFBuffer(storage);
var data = new ExportingGltfData();
// var buffer = new glTFBuffer(storage);
var values = new List<byte>();
int offset = 0;
@@ -139,11 +140,11 @@ namespace UniGLTF
values.AddRange(nums);
var bytes = new ArraySegment<Byte>(nums);
offset += x;
buffer.Append(bytes, glBufferTarget.NONE);
data.ExtendBufferAndGetView(bytes, glBufferTarget.NONE);
}
Assert.AreEqual(values.Count, buffer.byteLength);
Assert.True(Enumerable.SequenceEqual(values, buffer.GetBytes().ToArray()));
Assert.AreEqual(values.Count, data.GLTF.buffers[0].byteLength);
Assert.True(Enumerable.SequenceEqual(values, data.BinBytes.ToArray()));
}
[Test]
@@ -553,9 +554,7 @@ namespace UniGLTF
// import
{
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
var parsed = new JsonWithStorageParser(json, storage).Parse();
var parsed = GltfData.CreateFromExportForTest(data);
using (var context = new ImporterContext(parsed))
using (var loaded = context.Load())
{
@@ -573,10 +572,7 @@ namespace UniGLTF
// import new version
{
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
var parsed = new JsonWithStorageParser(json, storage).Parse();
//Debug.LogFormat("{0}", context.Json);
var parsed = GltfData.CreateFromExportForTest(data);
using (var context = new ImporterContext(parsed))
using (var loaded = context.Load())
{
@@ -628,9 +624,7 @@ namespace UniGLTF
// import
{
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
var parsed = new JsonWithStorageParser(json, storage).Parse();
var parsed = GltfData.CreateFromExportForTest(data);
using (var context = new ImporterContext(parsed))
using (var loaded = context.Load())
{
@@ -694,9 +688,7 @@ namespace UniGLTF
// import
{
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
var parsed = new JsonWithStorageParser(json, storage).Parse();
var parsed = GltfData.CreateFromExportForTest(data);
using (var context = new ImporterContext(parsed))
using (var loaded = context.Load())
{

View File

@@ -58,7 +58,8 @@ namespace VRM
}
},
}
}
},
default
);
var vrm = new glTF_VRM_extensions
{
@@ -119,7 +120,8 @@ namespace VRM
}
},
}
}
},
default
);
var vrm = new glTF_VRM_extensions
{

View File

@@ -39,7 +39,7 @@ namespace UniVRM10
count = self.Count;
}
var slice = self.Bytes.Slice(offset * stride, count * stride);
return storage.AppendToBuffer(bufferIndex, slice);
return storage.AppendToBuffer(slice);
}
static glTFAccessor CreateGltfAccessor(this VrmLib.BufferAccessor self,
@@ -116,8 +116,8 @@ namespace UniVRM10
sparseValueSpan[i] = value;
}
var sparseIndexView = storage.AppendToBuffer(bufferIndex, sparseIndexBin);
var sparseValueView = storage.AppendToBuffer(bufferIndex, sparseValueBin);
var sparseIndexView = storage.AppendToBuffer(sparseIndexBin);
var sparseValueView = storage.AppendToBuffer(sparseValueBin);
var accessorIndex = storage.Gltf.accessors.Count;
var accessor = new glTFAccessor

View File

@@ -110,7 +110,7 @@ namespace UniVRM10
GetTextureBytesAsync getThumbnailImageBytesAsync = () =>
{
var bytes = data.GetImageBytes(imageIndex);
var bytes = data.GetBytesFromImage(imageIndex);
return Task.FromResult(GltfTextureImporter.ToArray(bytes));
};
var texDesc = new TextureDescriptor(objectName, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default,

View File

@@ -15,8 +15,6 @@ namespace UniVRM10
UniGLTF.GltfData m_data;
public UniGLTF.glTF Gltf => m_data.GLTF;
public List<UniGLTF.IBytesBuffer> Buffers;
public UniGLTF.Extensions.VRMC_vrm.VRMC_vrm gltfVrm;
public UniGLTF.Extensions.VRMC_springBone.VRMC_springBone gltfVrmSpringBone;
@@ -31,13 +29,9 @@ namespace UniVRM10
string.Empty,
GLTF,
new List<GlbChunk>(),
new SimpleStorage(new ArraySegment<byte>()),
default,
new MigrationFlags()
);
Buffers = new List<UniGLTF.IBytesBuffer>()
{
new UniGLTF.ArrayByteBuffer()
};
}
/// <summary>
@@ -61,20 +55,17 @@ namespace UniVRM10
gltfVrmSpringBone = springBone;
}
Buffers = new List<UniGLTF.IBytesBuffer>()
{
Gltf.buffers[0].Buffer,
};
_buffer = new ArraySegmentByteBuffer(data.Bin);
}
public void Reserve(int bytesLength)
{
Buffers[0].ExtendCapacity(bytesLength);
_buffer.ExtendCapacity(bytesLength);
}
public int AppendToBuffer(int bufferIndex, ArraySegment<byte> segment)
public int AppendToBuffer(ArraySegment<byte> segment)
{
var gltfBufferView = Buffers[bufferIndex].Extend(segment);
var gltfBufferView = _buffer.Extend(segment);
var viewIndex = Gltf.bufferViews.Count;
Gltf.bufferViews.Add(gltfBufferView);
return viewIndex;
@@ -138,7 +129,7 @@ namespace UniVRM10
var view = Gltf.bufferViews[bufferViewIndex];
if (view.buffer.TryGetValidIndex(Gltf.buffers.Count, out int bufferIndex))
{
var buffer = Buffers[bufferIndex];
var buffer = _buffer;
var bin = buffer.Bytes;
var byteSize = accessor.CalcByteSize();
bytes = bin.Slice(view.byteOffset, view.byteLength).Slice(accessor.byteOffset, byteSize);
@@ -480,18 +471,22 @@ namespace UniVRM10
public ArraySegment<byte> GetBufferBytes(UniGLTF.glTFBuffer buffer)
{
int index = Gltf.buffers.IndexOf(buffer);
return Buffers[index].Bytes;
if (index != 0)
{
throw new NotImplementedException();
}
return _buffer.Bytes;
}
public byte[] ToBytes()
{
Gltf.buffers[0].byteLength = Buffers[0].Bytes.Count;
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, Buffers[0].Bytes);
var glb = UniGLTF.Glb.Create(json, _buffer.Bytes);
return glb.ToBytes();
}
}

View File

@@ -69,7 +69,7 @@ namespace UniVRM10
// copy images
foreach (var image in gltf.images)
{
var bytes = _data.GetViewBytes(image.bufferView);
var bytes = _data.GetBytesFromBufferView(image.bufferView);
image.bufferView = AddBuffer(bytes);
}

View File

@@ -72,7 +72,7 @@ namespace UniVRM10
if (bufferViewIndex != -1)
{
var buffer = data.GetViewBytes(bufferViewIndex);
var buffer = data.GetBytesFromBufferView(bufferViewIndex);
var span = SpanLike.Wrap<UnityEngine.Vector3>(buffer);
for (int i = 0; i < span.Length; ++i)
{
@@ -113,7 +113,7 @@ namespace UniVRM10
if (used.Add(skin.inverseBindMatrices))
{
var accessor = data.GLTF.accessors[skin.inverseBindMatrices];
var buffer = data.GetViewBytes(accessor.bufferView);
var buffer = data.GetBytesFromBufferView(accessor.bufferView);
var span = SpanLike.Wrap<UnityEngine.Matrix4x4>(buffer);
for (int i = 0; i < span.Length; ++i)
{