Ejemplo n.º 1
0
        /// <summary>
        /// Turns the GLB data contained in a stream into a GLBObject. Will copy to the outStream if specified
        /// </summary>
        /// <param name="root">The glTF root to turn into a GLBObject</param>
        /// <param name="inputGLBStream">The stream the glb came in</param>
        /// <param name="outStream">If outstream is specified, the glb gets copied to it</param>
        /// <param name="inputGLBStreamStartPosition">Offset into the buffer that the GLB starts</param>
        /// <returns>A constructed GLBObject</returns>
        public static GLBObject ConstructFromGLB(GLTFRoot root, Stream inputGLBStream, Stream outStream = null,
                                                 long inputGLBStreamStartPosition = 0)
        {
            if (outStream != null)
            {
                inputGLBStream.Position = inputGLBStreamStartPosition;
                inputGLBStream.CopyTo(outStream);
            }
            else
            {
                outStream = inputGLBStream;
            }

            // header information is 4 bytes in, past the magic number
            inputGLBStream.Position = 4 + inputGLBStreamStartPosition;
            GLBHeader header = GLTFParser.ParseGLBHeader(inputGLBStream);

            inputGLBStream.Position = GLTFParser.HEADER_SIZE + inputGLBStreamStartPosition;
            List <ChunkInfo> allChunks     = GLTFParser.FindChunks(inputGLBStream);
            ChunkInfo        jsonChunkInfo = new ChunkInfo
            {
                Type = ChunkFormat.JSON
            };
            ChunkInfo binaryChunkInfo = new ChunkInfo
            {
                Type = ChunkFormat.BIN
            };

            foreach (ChunkInfo chunkInfo in allChunks)
            {
                switch (chunkInfo.Type)
                {
                case ChunkFormat.JSON:
                    jsonChunkInfo = chunkInfo;
                    break;

                case ChunkFormat.BIN:
                    binaryChunkInfo = chunkInfo;
                    break;
                }
            }

            if (jsonChunkInfo.Length == 0)
            {
                throw new ArgumentException("JSON chunk must exists for valid GLB", nameof(inputGLBStream));
            }

            // todo: compute the initial bufferview list
            return(new GLBObject
            {
                Root = root,
                Stream = outStream,
                StreamStartPosition = inputGLBStreamStartPosition,
                Header = header,
                JsonChunkInfo = jsonChunkInfo,
                BinaryChunkInfo = binaryChunkInfo
            });
        }
Ejemplo n.º 2
0
        private static void WriteChunkHeader(Stream stream, ChunkInfo chunkInfo)
        {
            stream.Position = chunkInfo.StartPosition;
            byte[] lengthBytes = BitConverter.GetBytes(chunkInfo.Length);
            byte[] typeBytes   = BitConverter.GetBytes((uint)chunkInfo.Type);

            stream.Write(lengthBytes, 0, lengthBytes.Length);
            stream.Write(typeBytes, 0, lengthBytes.Length);
        }
Ejemplo n.º 3
0
        public static ChunkInfo ParseChunkInfo(Stream stream)
        {
            ChunkInfo chunkInfo = new ChunkInfo
            {
                StartPosition = stream.Position
            };

            chunkInfo.Length = GetUInt32(stream);                                       // 12
            chunkInfo.Type   = (ChunkFormat)GetUInt32(stream);                          // 16
            return(chunkInfo);
        }
Ejemplo n.º 4
0
        private static void ParseJsonChunk(Stream stream, long startPosition)
        {
            GLBHeader header = ParseGLBHeader(stream);              // 4, 8

            if (header.Version != 2)
            {
                throw new GLTFHeaderInvalidException("Unsupported glTF version");
            }
            ;

            if (header.FileLength != (stream.Length - startPosition))
            {
                throw new GLTFHeaderInvalidException("File length does not match header.");
            }

            ChunkInfo chunkInfo = ParseChunkInfo(stream);

            if (chunkInfo.Type != ChunkFormat.JSON)
            {
                throw new GLTFHeaderInvalidException("First chunk must be of type JSON");
            }
        }
Ejemplo n.º 5
0
        public static List <ChunkInfo> FindChunks(Stream stream, long startPosition = 0)
        {
            stream.Position = startPosition + 4;                 // start after magic number bytes (4 bytes past)
            ParseGLBHeader(stream);
            List <ChunkInfo> allChunks = new List <ChunkInfo>();

            // we only need to search for top two chunks (the JSON and binary chunks are guarenteed to be the top two chunks)
            // other chunks can be in the file but we do not care about them
            for (int i = 0; i < 2; ++i)
            {
                if (stream.Position == stream.Length)
                {
                    break;
                }

                ChunkInfo chunkInfo = ParseChunkInfo(stream);
                allChunks.Add(chunkInfo);
                stream.Position += chunkInfo.Length;
            }

            return(allChunks);
        }