diff --git a/Packages/UniGLTF/Runtime/UniGLTF/IO/NativeArrayMemoryManager.cs b/Packages/UniGLTF/Runtime/UniGLTF/IO/NativeArrayMemoryManager.cs new file mode 100644 index 000000000..33e789e88 --- /dev/null +++ b/Packages/UniGLTF/Runtime/UniGLTF/IO/NativeArrayMemoryManager.cs @@ -0,0 +1,70 @@ +using System; +using System.Buffers; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; + +namespace UniGLTF +{ + public static class NativeArrayExtensions + { +#if !UNITY_2023_2_OR_NEWER + public static unsafe Span AsSpan(this NativeArray nativeArray) where T : unmanaged + { + return new Span(nativeArray.GetUnsafePtr(), nativeArray.Length); + } +#endif + + public static unsafe Memory AsMemory(this NativeArray nativeArray) where T : unmanaged + { + return new NativeArrayMemoryManager((T*)nativeArray.GetUnsafeReadOnlyPtr(), nativeArray.Length).Memory; + } + + public static unsafe ReadOnlyMemory AsMemory(this NativeArray.ReadOnly nativeArray) where T : unmanaged + { + return new NativeArrayMemoryManager((T*)nativeArray.GetUnsafeReadOnlyPtr(), nativeArray.Length).Memory; + } + } + + unsafe class NativeArrayMemoryManager : MemoryManager where T : unmanaged + { + public T* Ptr { get; set; } + public int Length { get; set; } + + public NativeArrayMemoryManager(NativeArray nativeArray) + : this((T*)nativeArray.GetUnsafeReadOnlyPtr(), nativeArray.Length) + { + } + + public NativeArrayMemoryManager(T* ptr, int length) + { + if (length < 0) throw new ArgumentOutOfRangeException(nameof(length)); + Ptr = ptr; + Length = length; + } + + public override Span GetSpan() => new(Ptr, Length); + + /// + /// Provides access to a pointer that represents the data (note: no actual pin occurs) + /// + public override MemoryHandle Pin(int elementIndex = 0) + { + if (elementIndex < 0 || elementIndex >= Length) + { + throw new ArgumentOutOfRangeException(nameof(Length)); + } + return new MemoryHandle(Ptr + elementIndex); + } + + /// + /// Has no effect + /// + public override void Unpin() + { + } + + protected override void Dispose(bool disposing) + { + } + } +} \ No newline at end of file diff --git a/Packages/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs b/Packages/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs index d092ea6e9..077681b47 100644 --- a/Packages/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs +++ b/Packages/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; using System.Text.RegularExpressions; using UniJSON; +using Unity.Collections; namespace UniGLTF { @@ -17,7 +17,7 @@ namespace UniGLTF private static readonly Regex _removeUniqueFixResourceSuffix = new Regex($@"^(.+){UniqueFixResourceSuffix}(\d+)$"); private readonly string _path; - private readonly byte[] _binary; + private readonly ReadOnlyMemory _binary; public GlbLowLevelParser(string path, byte[] specifiedBinary) { @@ -25,8 +25,20 @@ namespace UniGLTF _binary = specifiedBinary; } + public GlbLowLevelParser(string path, NativeArray specifiedBinary) + { + _path = path; + _binary = specifiedBinary.AsMemory(); + } + public GltfData Parse() => Parse(_path, _binary); + public static GltfData Parse(string path, NativeArray binary) => + Parse(path, binary.AsMemory()); + + public static GltfData Parse(string path, byte[] binary) => + Parse(path, binary.AsMemory()); + public static GltfData Parse(string path, ReadOnlyMemory binary) { try @@ -87,6 +99,7 @@ namespace UniGLTF { var jsonNode = json.ParseAsJson(); var GLTF = GltfDeserializer.Deserialize(jsonNode); + if (!GLTF.asset.version.StartsWith("2")) { throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version); }