Пример #1
0
        /// <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));
            }
        }
Пример #2
0
        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));
        }
Пример #3
0
        /// <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);
            }
        }