mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-14 22:36:28 -05:00
IByteBuffer and glTFBuffer decoupling.
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c103da8b4a2b4050be09e7bfce2769fd
|
||||
timeCreated: 1624803637
|
||||
@@ -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",
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace UniGLTF
|
||||
string.Empty,
|
||||
gltf,
|
||||
new List<GlbChunk>(),
|
||||
new SimpleStorage(new ArraySegment<byte>()),
|
||||
default,
|
||||
new MigrationFlags()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user