mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-03-21 18:05:03 -05:00
Merge pull request #2744 from Akeit0/optimize-parser
Optimize Glb parser
This commit is contained in:
commit
82e4f707f3
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using UniJSON;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace UniGLTF
|
||||
|
|
@ -32,7 +33,7 @@ namespace UniGLTF
|
|||
/// JSON chunk ToString
|
||||
/// > This chunk MUST be the very first chunk of Binary glTF asset
|
||||
/// </summary>
|
||||
public string Json { get; }
|
||||
public string Json => _jsonString ??= _utf8JsonString.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// GLTF parsed from JSON chunk
|
||||
|
|
@ -72,10 +73,39 @@ namespace UniGLTF
|
|||
/// <returns></returns>
|
||||
Dictionary<string, NativeArray<byte>> _UriCache = new Dictionary<string, NativeArray<byte>>();
|
||||
|
||||
/// <summary>
|
||||
/// json string in utf8
|
||||
/// </summary>
|
||||
Utf8String _utf8JsonString;
|
||||
|
||||
/// <summary>
|
||||
/// json string cache
|
||||
/// </summary>
|
||||
string _jsonString;
|
||||
|
||||
public GltfData(string targetPath, string json, glTF gltf, IReadOnlyList<GlbChunk> chunks, IStorage storage, MigrationFlags migrationFlags)
|
||||
{
|
||||
TargetPath = targetPath;
|
||||
Json = json;
|
||||
_jsonString = json;
|
||||
GLTF = gltf;
|
||||
Chunks = chunks;
|
||||
_storage = storage;
|
||||
MigrationFlags = migrationFlags;
|
||||
|
||||
// init
|
||||
if (Chunks != null)
|
||||
{
|
||||
if (Chunks.Count >= 2)
|
||||
{
|
||||
Bin = NativeArrayManager.CreateNativeArray(Chunks[1].Bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal GltfData(string targetPath, Utf8String jsonString, glTF gltf, IReadOnlyList<GlbChunk> chunks, IStorage storage, MigrationFlags migrationFlags)
|
||||
{
|
||||
TargetPath = targetPath;
|
||||
_utf8JsonString = jsonString;
|
||||
GLTF = gltf;
|
||||
Chunks = chunks;
|
||||
_storage = storage;
|
||||
|
|
@ -441,4 +471,4 @@ namespace UniGLTF
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UniJSON;
|
||||
|
||||
|
|
@ -33,7 +32,7 @@ namespace UniGLTF
|
|||
var jsonBytes = chunks[0].Bytes;
|
||||
return ParseGltf(
|
||||
_path,
|
||||
Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count),
|
||||
new Utf8String(new ArraySegment<byte>(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count)),
|
||||
chunks,
|
||||
default,
|
||||
new MigrationFlags()
|
||||
|
|
@ -73,14 +72,20 @@ namespace UniGLTF
|
|||
|
||||
public static GltfData ParseGltf(string path, string json, IReadOnlyList<GlbChunk> chunks, IStorage storage, MigrationFlags migrationFlags)
|
||||
{
|
||||
var GLTF = GltfDeserializer.Deserialize(json.ParseAsJson());
|
||||
return ParseGltf(path, Utf8String.From(json), chunks, storage, migrationFlags);
|
||||
}
|
||||
|
||||
internal static GltfData ParseGltf(string path, Utf8String json, IReadOnlyList<GlbChunk> chunks, IStorage storage, MigrationFlags migrationFlags)
|
||||
{
|
||||
var parsedJson = json.ParseAsJson();
|
||||
var GLTF = GltfDeserializer.Deserialize(parsedJson);
|
||||
if (GLTF.asset.version != "2.0")
|
||||
{
|
||||
throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version);
|
||||
}
|
||||
|
||||
// Version Compatibility
|
||||
RestoreOlderVersionValues(json, GLTF);
|
||||
RestoreOlderVersionValues(parsedJson, GLTF);
|
||||
|
||||
FixMeshNameUnique(GLTF);
|
||||
FixBlendShapeNameUnique(GLTF);
|
||||
|
|
@ -298,9 +303,8 @@ namespace UniGLTF
|
|||
}
|
||||
}
|
||||
|
||||
private static void RestoreOlderVersionValues(string Json, glTF GLTF)
|
||||
private static void RestoreOlderVersionValues(JsonNode parsed, glTF GLTF)
|
||||
{
|
||||
var parsed = UniJSON.JsonParser.Parse(Json);
|
||||
for (int i = 0; i < GLTF.images.Count; ++i)
|
||||
{
|
||||
if (string.IsNullOrEmpty(GLTF.images[i].name))
|
||||
|
|
|
|||
|
|
@ -395,6 +395,28 @@ namespace UniJSON
|
|||
return writeCount;
|
||||
}
|
||||
|
||||
private static Utf8String Unescape(Utf8String s)
|
||||
{
|
||||
var span = s.AsSpan();
|
||||
var escapeIndex = span.IndexOf((byte)'\\');
|
||||
|
||||
// escape not found
|
||||
if (escapeIndex == -1)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
var sb = new BytesStore(s.ByteLength);
|
||||
foreach (var b in span[..escapeIndex])
|
||||
{
|
||||
sb.Write(b);
|
||||
}
|
||||
|
||||
Unescape(s.Subbytes(escapeIndex), sb);
|
||||
return new Utf8String(sb.Bytes);
|
||||
}
|
||||
|
||||
|
||||
public static string Unescape(string src)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
|
@ -430,18 +452,9 @@ namespace UniJSON
|
|||
|
||||
public static Utf8String Unquote(Utf8String src)
|
||||
{
|
||||
var count = Unquote(src, null);
|
||||
if (count == src.ByteLength - 2)
|
||||
{
|
||||
return src.Subbytes(1, src.ByteLength - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sb = new BytesStore(count);
|
||||
Unquote(src, sb);
|
||||
return new Utf8String(sb.Bytes);
|
||||
}
|
||||
return Unescape(src.Subbytes(1, src.ByteLength - 2));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ namespace UniJSON
|
|||
public UInt64 GetUInt64() { return Segment.ToUInt64(); }
|
||||
public Single GetSingle() { return Segment.ToSingle(); }
|
||||
public Double GetDouble() { return Segment.ToDouble(); }
|
||||
public String GetString() { return JsonString.Unquote(Segment.ToString()); }
|
||||
public String GetString() { return JsonString.Unquote(Segment).ToString(); }
|
||||
public Utf8String GetUtf8String() { return JsonString.Unquote(Segment); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -110,6 +110,8 @@ namespace UniJSON
|
|||
return new Utf8String(bytes);
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> AsSpan() => Bytes.AsSpan();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (ByteLength == 0) return "";
|
||||
|
|
@ -324,4 +326,4 @@ namespace UniJSON
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
|
||||
|
|
@ -320,11 +322,46 @@ namespace UniJSON
|
|||
|
||||
public static float ToSingle(this Utf8String src)
|
||||
{
|
||||
return Single.Parse(src.ToAscii(), System.Globalization.CultureInfo.InvariantCulture);
|
||||
char[] arrayToReturn = null;
|
||||
try
|
||||
{
|
||||
var srcBytes = src.AsSpan();
|
||||
Span<char> chars = srcBytes.Length < 64
|
||||
? stackalloc char[srcBytes.Length]
|
||||
: arrayToReturn = ArrayPool<char>.Shared.Rent(srcBytes.Length);
|
||||
var count = System.Text.Encoding.ASCII.GetChars(srcBytes, chars);
|
||||
return Single.Parse(chars[..count], NumberStyles.Float | NumberStyles.AllowThousands,
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (arrayToReturn != null)
|
||||
{
|
||||
ArrayPool<char>.Shared.Return(arrayToReturn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static double ToDouble(this Utf8String src)
|
||||
{
|
||||
return Double.Parse(src.ToAscii(), System.Globalization.CultureInfo.InvariantCulture);
|
||||
char[] arrayToReturn = null;
|
||||
try
|
||||
{
|
||||
var srcBytes = src.AsSpan();
|
||||
Span<char> chars = srcBytes.Length < 64
|
||||
? stackalloc char[srcBytes.Length]
|
||||
: arrayToReturn = ArrayPool<char>.Shared.Rent(srcBytes.Length);
|
||||
var count = System.Text.Encoding.ASCII.GetChars(srcBytes, chars);
|
||||
return Double.Parse(chars[..count], NumberStyles.Float | NumberStyles.AllowThousands,
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (arrayToReturn != null)
|
||||
{
|
||||
ArrayPool<char>.Shared.Return(arrayToReturn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Utf8String GetLine(this Utf8String src)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user