GLTFBuffer.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Threading.Tasks;
  5. using Newtonsoft.Json;
  6. using UnityEngine;
  7. using UnityEngine.Scripting;
  8. namespace Siccity.GLTFUtility {
  9. // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffer
  10. /// <summary> Contains raw binary data </summary>
  11. [Preserve] public class GLTFBuffer {
  12. [JsonProperty(Required = Required.Always)] public int byteLength;
  13. public string uri;
  14. public string name;
  15. [JsonIgnore] private const string embeddedPrefix = "data:application/octet-stream;base64,";
  16. [JsonIgnore] private const string embeddedPrefix2 = "data:application/gltf-buffer;base64,";
  17. public class ImportResult {
  18. public Stream stream;
  19. public long startOffset;
  20. public void Dispose() {
  21. stream.Dispose();
  22. }
  23. }
  24. #region Import
  25. /// <param name="filepath">Filepath if loading from a file</param>
  26. /// <param name="bytefile">bytes if loading from raw bytes</param>
  27. public ImportResult Import(string filepath, byte[] bytefile, long binChunkStart) {
  28. ImportResult result = new ImportResult();
  29. if (uri == null) {
  30. // Load entire file
  31. if (string.IsNullOrEmpty(filepath)) result.stream = new MemoryStream(bytefile);
  32. else result.stream = File.OpenRead(filepath);
  33. result.startOffset = binChunkStart + 8;
  34. result.stream.Position = result.startOffset;
  35. } else if (uri.StartsWith(embeddedPrefix)) {
  36. // Load embedded
  37. string b64 = uri.Substring(embeddedPrefix.Length, uri.Length - embeddedPrefix.Length);
  38. byte[] bytes = Convert.FromBase64String(b64);
  39. result.stream = new MemoryStream(bytes);
  40. } else if (uri.StartsWith(embeddedPrefix2)) {
  41. // Load embedded
  42. string b64 = uri.Substring(embeddedPrefix2.Length, uri.Length - embeddedPrefix2.Length);
  43. byte[] bytes = Convert.FromBase64String(b64);
  44. result.stream = new MemoryStream(bytes);
  45. } else {
  46. // Load URI
  47. string directoryRoot = Directory.GetParent(filepath).ToString() + "/";
  48. result.stream = File.OpenRead(directoryRoot + uri);
  49. result.startOffset = result.stream.Length - byteLength;
  50. }
  51. return result;
  52. }
  53. public class ImportTask : Importer.ImportTask<ImportResult[]> {
  54. /// <param name="filepath">Filepath if loading from a file</param>
  55. /// <param name="bytefile">bytes if loading from raw bytes</param>
  56. public ImportTask(List<GLTFBuffer> buffers, string filepath, byte[] bytefile, long binChunkStart) : base() {
  57. task = new Task(() => {
  58. Result = new ImportResult[buffers.Count];
  59. for (int i = 0; i < Result.Length; i++) {
  60. Result[i] = buffers[i].Import(filepath, bytefile, binChunkStart);
  61. }
  62. });
  63. }
  64. }
  65. #endregion
  66. }
  67. }