/// <summary> /// parse from stream /// </summary> /// <param name="stream"></param> /// <returns></returns> public static GltfResult <GlbFile> Parse(Stream stream) { using (var br = new BinaryReader(stream)) { var headerRes = GlbHeader.Parse(br); if (headerRes.Error != null) { return(Result.Error <GlbFile>(headerRes.Error)); } var header = headerRes.Data; var glbLen = header.Length - GlbConsts.HeaderLength; var cHeaderRes = ChunkHeader.Parse(br); if (cHeaderRes.Error != null) { return(Result.Error <GlbFile>(cHeaderRes.Error)); } var cHeader = cHeaderRes.Data; if (cHeader.ChunkType != ChunkType.Json) { return(Result.Error <GlbFile>(new GltfException( new[] { new GltfError { Kind = ErrorKind.Glb, Message = "Missing Json Chunk" } } ))); } var jsonBytes = br.ReadBytes((int)cHeader.Length); var gFile = new GlbFile { Header = header, Json = jsonBytes }; var binLen = glbLen - cHeader.Length; if (binLen > 0) { var bHeaderRes = ChunkHeader.Parse(br); if (bHeaderRes.Error != null) { return(Result.Error <GlbFile>(bHeaderRes.Error)); } var bHeader = bHeaderRes.Data; if (bHeader.ChunkType != ChunkType.Bin) { return(Result.Error <GlbFile>(new GltfException( new[] { new GltfError { Kind = ErrorKind.Glb, Message = "Must be Bin Chunk after Json Chunk" } } ))); } gFile.Bin = br.ReadBytes((int)bHeader.Length); } return(Result.Ok(gFile)); } }
internal static GltfResult <GlbHeader> Parse(BinaryReader br) { var magic = br.ReadUInt32(); if (magic != GlbConsts.Magic) { return(Result.Error <GlbHeader>(new GltfException( new[] { new GltfError { Kind = ErrorKind.Glb, Message = "Magic number not match" } }))); } var version = br.ReadUInt32(); if (version != GlbConsts.Version) { return(Result.Error <GlbHeader>(new GltfException( new[] { new GltfError { Kind = ErrorKind.Glb, Message = "Version not match" } }))); } var length = br.ReadUInt32(); if (length == 0) { return(Result.Error <GlbHeader>(new GltfException( new[] { new GltfError { Kind = ErrorKind.Glb, Message = "buffer length is zero" } }))); } var header = new GlbHeader { Magic = magic, Version = version, Length = length }; return(Result.Ok(header)); }
/// <summary> /// write model to filePath /// </summary> /// <param name="model"></param> /// <param name="filePath"></param> public void WriteModel(Model model, string filePath) { if (UriUtil.IsValidUri(model.Uri)) { model.WriteUriFiles(filePath); } var ext = Path.GetExtension(filePath).TrimStart('.').ToUpper(); if (ext == "GLB") { using (var fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write)) using (var bw = new BinaryWriter(fs)) { var binCount = 0; var byteLength = 0; if (model.BinBuffers != null) { byteLength = model.BinBuffers.Count; Padding(model.BinBuffers, 4); binCount += model.BinBuffers.Count; if (model.Buffers.Count == 0) { var buffer = new Json.Buffer(); model.Buffers.Add(buffer); } model.Buffers[0].ByteLength = byteLength; } var json = JsonUtil.ToJson(model); var jsonBytes = new List <byte>(JsonUtil.StrEncoding.GetBytes(json)); PaddingSpace(jsonBytes, 4); var len = GlbHeader.ByteCount + jsonBytes.Count + binCount + 8 + (binCount > 0 ? 8 : 0); var header = GlbHeader.GetGlbHeader((uint)len); header.Write(bw); var jsonChunk = new ChunkHeader { ChunkType = ChunkType.Json, Length = (uint)jsonBytes.Count }; jsonChunk.Write(bw); for (var i = 0; i < jsonBytes.Count; i++) { bw.Write(jsonBytes[i]); } if (model.BinBuffers != null) { var binChunk = new ChunkHeader { ChunkType = ChunkType.Bin, Length = (uint)model.BinBuffers.Count }; binChunk.Write(bw); for (var i = 0; i < model.BinBuffers.Count; i++) { bw.Write(model.BinBuffers[i]); } } bw.Flush(); } } else { JsonUtil.Serialize(model, filePath); } }