IByteBuffer and glTFBuffer decoupling.

This commit is contained in:
ousttrue
2021-10-27 19:01:42 +09:00
parent 95c3c7c5d4
commit b8aad0cc63
14 changed files with 65 additions and 187 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

@@ -11,17 +11,37 @@ namespace UniGLTF
public glTF GLTF => _gltf;
protected IBytesBuffer _buffer;
/// <summary>
/// bin chunk
/// </summary>
public ArraySegment<byte> BinBytes => _buffer.Bytes;
public ExportingGltfData(int reserved = default)
{
if (reserved == 0)
{
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 Append<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 glTFBufferView Append<T>(T[] array, glBufferTarget target) where T : struct
{
return Append(new ArraySegment<T>(array), target);
}
public int ExtendBufferAndGetViewIndex<T>(
ArraySegment<T> array,
glBufferTarget target = glBufferTarget.NONE) where T : struct
@@ -30,7 +50,7 @@ namespace UniGLTF
{
return -1;
}
var view = _gltf.buffers[0].Append(array, target);
var view = Append(array, target);
var viewIndex = _gltf.bufferViews.Count;
_gltf.bufferViews.Add(view);
return viewIndex;
@@ -185,8 +205,6 @@ namespace UniGLTF
return f.ToString();
}
public ArraySegment<byte> BinBytes => _gltf.buffers[0].GetBytes();
/// <summary>
/// GLBバイト列
/// </summary>
@@ -207,7 +225,7 @@ 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)
@@ -224,7 +242,7 @@ namespace UniGLTF
GltfSerializer.Serialize(f, _gltf);
var json = f.ToString().ParseAsJson().ToString(" ");
RemoveUnusedExtensions(_gltf, json);
return (json, _gltf.buffers);
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

@@ -85,15 +85,6 @@ namespace UniGLTF
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,
@@ -102,7 +93,7 @@ namespace UniGLTF
new GlbChunk(), // json
GlbChunk.CreateBin(bytes),
},
storage,
default,
new MigrationFlags()
);
}

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

@@ -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

@@ -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.CreateFromExport(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.Append(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]
@@ -623,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.CreateFromExport(data);
using (var context = new ImporterContext(parsed))
using (var loaded = context.Load())
{
@@ -689,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.CreateFromExport(data);
using (var context = new ImporterContext(parsed))
using (var loaded = context.Load())
{

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

@@ -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();
}
}