mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-27 13:23:44 -05:00
GlbLowLevelParserの入力をMemoryでとれるようにする
This commit is contained in:
@@ -28,10 +28,11 @@ namespace UniGLTF
|
||||
|
||||
public struct GlbChunk
|
||||
{
|
||||
public GlbChunkType ChunkType => ChunkTypeString.ToChunkType();
|
||||
public GlbChunkType ChunkType => ChunkTypeBytes.ToChunkType();
|
||||
|
||||
public string ChunkTypeString;
|
||||
public ArraySegment<Byte> Bytes;
|
||||
public string ChunkTypeString => Encoding.ASCII.GetString(ChunkTypeBytes.Span);
|
||||
public ReadOnlyMemory<byte> Bytes;
|
||||
public ReadOnlyMemory<byte> ChunkTypeBytes;
|
||||
|
||||
public GlbChunk(string json) : this(
|
||||
GlbChunkType.JSON.ToChunkTypeString(),
|
||||
@@ -49,7 +50,13 @@ namespace UniGLTF
|
||||
|
||||
public GlbChunk(string chunkTypeString, ArraySegment<Byte> bytes)
|
||||
{
|
||||
ChunkTypeString = chunkTypeString;
|
||||
ChunkTypeBytes = Encoding.ASCII.GetBytes(chunkTypeString);
|
||||
Bytes = bytes;
|
||||
}
|
||||
|
||||
public GlbChunk(ReadOnlyMemory<byte> chunkTypeBytes, ReadOnlyMemory<byte> bytes)
|
||||
{
|
||||
ChunkTypeBytes = chunkTypeBytes;
|
||||
Bytes = bytes;
|
||||
}
|
||||
|
||||
@@ -60,12 +67,12 @@ namespace UniGLTF
|
||||
|
||||
public static GlbChunk CreateJson(ArraySegment<byte> bytes)
|
||||
{
|
||||
return new GlbChunk(GlbChunkType.JSON.ToChunkTypeString(), bytes);
|
||||
return new GlbChunk(glbImporter.GLB_JSON_BYTES, bytes);
|
||||
}
|
||||
|
||||
public static GlbChunk CreateBin(ArraySegment<Byte> bytes)
|
||||
{
|
||||
return new GlbChunk(GlbChunkType.BIN.ToChunkTypeString(), bytes);
|
||||
return new GlbChunk(glbImporter.GLB_BIN_BYTES, bytes);
|
||||
}
|
||||
|
||||
byte GetPaddingByte()
|
||||
@@ -87,11 +94,11 @@ namespace UniGLTF
|
||||
public int WriteTo(Stream s)
|
||||
{
|
||||
// padding
|
||||
var paddingValue = Bytes.Count % 4;
|
||||
var paddingValue = Bytes.Length % 4;
|
||||
var padding = (paddingValue > 0) ? 4 - paddingValue : 0;
|
||||
|
||||
// size
|
||||
var bytes = BitConverter.GetBytes((int)(Bytes.Count + padding));
|
||||
var bytes = BitConverter.GetBytes((int)(Bytes.Length + padding));
|
||||
s.Write(bytes, 0, bytes.Length);
|
||||
|
||||
// chunk type
|
||||
@@ -116,7 +123,7 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
// body
|
||||
s.Write(Bytes.Array, Bytes.Offset, Bytes.Count);
|
||||
s.Write(Bytes.Span);
|
||||
|
||||
// 4byte align
|
||||
var pad = GetPaddingByte();
|
||||
@@ -125,7 +132,7 @@ namespace UniGLTF
|
||||
s.WriteByte(pad);
|
||||
}
|
||||
|
||||
return 4 + 4 + Bytes.Count + padding;
|
||||
return 4 + 4 + Bytes.Length + padding;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,15 @@ namespace UniGLTF
|
||||
return array;
|
||||
}
|
||||
|
||||
public NativeArray<T> CreateNativeArray<T>(ReadOnlyMemory<T> data) where T : struct
|
||||
{
|
||||
var array = CreateNativeArray<T>(data.Length);
|
||||
var toSpan = array.AsSpan();
|
||||
var fromSpan = data.Span;
|
||||
fromSpan.CopyTo(toSpan);
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// サイズの違う型にコピーする。
|
||||
///
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UniJSON;
|
||||
|
||||
@@ -24,15 +25,17 @@ namespace UniGLTF
|
||||
_binary = specifiedBinary;
|
||||
}
|
||||
|
||||
public GltfData Parse()
|
||||
public GltfData Parse() => Parse(_path, _binary);
|
||||
|
||||
public static GltfData Parse(string path, ReadOnlyMemory<byte> binary)
|
||||
{
|
||||
try
|
||||
{
|
||||
var chunks = ParseGlbChunks(_binary);
|
||||
var chunks = ParseGlbChunks(binary);
|
||||
var jsonBytes = chunks[0].Bytes;
|
||||
return ParseGltf(
|
||||
_path,
|
||||
new Utf8String(new ArraySegment<byte>(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count)),
|
||||
path,
|
||||
Encoding.UTF8.GetString(jsonBytes.Span),
|
||||
chunks,
|
||||
default,
|
||||
new MigrationFlags()
|
||||
@@ -48,7 +51,7 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
public static List<GlbChunk> ParseGlbChunks(byte[] data)
|
||||
public static List<GlbChunk> ParseGlbChunks(ReadOnlyMemory<byte> data)
|
||||
{
|
||||
var chunks = glbImporter.ParseGlbChunks(data);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
@@ -9,7 +8,11 @@ namespace UniGLTF
|
||||
public static class glbImporter
|
||||
{
|
||||
public const string GLB_MAGIC = "glTF";
|
||||
public const float GLB_VERSION = 2.0f;
|
||||
public const uint GLB_VERSION = 2;
|
||||
|
||||
public static readonly ReadOnlyMemory<byte> GLB_MAGIC_BYTES = Encoding.ASCII.GetBytes(GLB_MAGIC);
|
||||
public static readonly ReadOnlyMemory<byte> GLB_JSON_BYTES = BitConverter.GetBytes((uint)GlbChunkType.JSON);
|
||||
public static readonly ReadOnlyMemory<byte> GLB_BIN_BYTES = BitConverter.GetBytes((uint)GlbChunkType.BIN);
|
||||
|
||||
public static GlbChunkType ToChunkType(this string src)
|
||||
{
|
||||
@@ -39,13 +42,30 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
public static GlbChunkType ToChunkType(this ReadOnlyMemory<byte> src)
|
||||
{
|
||||
if (src.Length != 4)
|
||||
{
|
||||
throw new FormatException("invalid chunk type: " + src);
|
||||
}
|
||||
if (src.Span.SequenceEqual(GLB_JSON_BYTES.Span))
|
||||
{
|
||||
return GlbChunkType.JSON;
|
||||
}
|
||||
if (src.Span.SequenceEqual(GLB_BIN_BYTES.Span))
|
||||
{
|
||||
return GlbChunkType.BIN;
|
||||
}
|
||||
throw new FormatException("unknown chunk type: " + src);
|
||||
}
|
||||
|
||||
[Obsolete("Use ParseGlbChunks(bytes)")]
|
||||
public static List<GlbChunk> ParseGlbChanks(Byte[] bytes)
|
||||
{
|
||||
return ParseGlbChunks(bytes);
|
||||
}
|
||||
|
||||
public static List<GlbChunk> ParseGlbChunks(Byte[] bytes)
|
||||
public static List<GlbChunk> ParseGlbChunks(ReadOnlyMemory<byte> bytes)
|
||||
{
|
||||
//
|
||||
// glb header(12byte)
|
||||
@@ -56,20 +76,20 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
if (Encoding.ASCII.GetString(bytes, 0, 4) != GLB_MAGIC)
|
||||
if (!bytes[..4].Span.SequenceEqual(GLB_MAGIC_BYTES.Span))
|
||||
{
|
||||
throw new GlbParseException("invalid magic");
|
||||
}
|
||||
pos += 4;
|
||||
|
||||
var version = BitConverter.ToUInt32(bytes, pos);
|
||||
var version = BitConverter.ToUInt32(bytes[pos..].Span);
|
||||
if (version != GLB_VERSION)
|
||||
{
|
||||
throw new GlbParseException($"unknown version: {version}");
|
||||
}
|
||||
pos += 4;
|
||||
|
||||
var totalLength = BitConverter.ToUInt32(bytes, pos);
|
||||
var totalLength = BitConverter.ToUInt32(bytes[pos..].Span);
|
||||
if (bytes.Length < totalLength)
|
||||
{
|
||||
throw new GlbParseException($"not enough size: {bytes.Length} < {totalLength}");
|
||||
@@ -79,19 +99,13 @@ namespace UniGLTF
|
||||
var chunks = new List<GlbChunk>();
|
||||
while (pos < bytes.Length)
|
||||
{
|
||||
var chunkDataSize = BitConverter.ToInt32(bytes, pos);
|
||||
var chunkDataSize = BitConverter.ToInt32(bytes[pos..].Span);
|
||||
pos += 4;
|
||||
|
||||
//var type = (GlbChunkType)BitConverter.ToUInt32(bytes, pos);
|
||||
var chunkTypeBytes = bytes.Skip(pos).Take(4).Where(x => x != 0).ToArray();
|
||||
var chunkTypeStr = Encoding.ASCII.GetString(chunkTypeBytes);
|
||||
var chunkTypeBytes = bytes.Slice(pos, 4);
|
||||
pos += 4;
|
||||
|
||||
chunks.Add(new GlbChunk
|
||||
{
|
||||
ChunkTypeString = chunkTypeStr,
|
||||
Bytes = new ArraySegment<byte>(bytes, (int)pos, (int)chunkDataSize)
|
||||
});
|
||||
chunks.Add(new GlbChunk(chunkTypeBytes, bytes.Slice(pos, chunkDataSize)));
|
||||
|
||||
pos += chunkDataSize;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace UniGLTF
|
||||
{
|
||||
|
||||
// glb header + 1st chunk only
|
||||
var mod = bytes.Take(12 + 8 + data.Chunks[0].Bytes.Count).ToArray();
|
||||
var mod = bytes.Take(12 + 8 + data.Chunks[0].Bytes.Length).ToArray();
|
||||
|
||||
Assert.Throws<GlbParseException>(() =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user