public void Read(EndianBinaryReader er)
        {
            GrannyUtils.SubreadUInt64Pointer(
                er, ser => { this.Name = ser.ReadStringNT(); });

            this.ParentIndex = er.ReadInt32();

            // granny_transform
            var transform = new GrannyTransform();

            transform.Read(er);
            this.LocalTransform = transform;

            // inverse_world_4x4
            for (var y = 0; y < 4; ++y)
            {
                for (var x = 0; x < 4; x++)
                {
                    this.InverseWorld4x4[x, y] = er.ReadSingle();
                }
            }

            // lod_error
            er.Position += 4;

            // extended_data
            er.Position += 2 * 8;

            ;
        }
        public void Read(EndianBinaryReader er)
        {
            var name = "";

            GrannyUtils.SubreadUInt64Pointer(er, ser => name = ser.ReadStringNT());

            ;
        }
        public void Read(EndianBinaryReader er)
        {
            GrannyUtils.SubreadUInt64Pointer(
                er, ser => { this.Name = ser.ReadStringNT(); });

            var boneCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(er, ser => {
                for (var i = 0; i < boneCount; ++i)
                {
                    Bones.Add(ser.ReadNew <GrannyBone>());
                }
            });
        }
        public void Read(EndianBinaryReader er)
        {
            GrannyUtils.SubreadUInt64Pointer(
                er, ser => { this.Name = ser.ReadStringNT(); });

            this.Duration     = er.ReadSingle();
            this.TimeStep     = er.ReadSingle();
            this.Oversampling = er.ReadSingle();

            var trackGroupCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(er, ser => {
                for (var i = 0; i < trackGroupCount; ++i)
                {
                    var trackGroup = new GrannyTrackGroup();
                    trackGroup.Read(ser);
                    this.TrackGroups.Add(trackGroup);
                }
            });
        }
        public void Read(EndianBinaryReader er)
        {
            // TODO: Make this offset-agnostic.
            // The reader passed into this method should have an offset of 0 at the
            // start of the granny_file_info object.
            Asserts.Equal(0, er.Position, "Expected to start reading at offset 0.");

            er.ReadUInt64(); // ArtToolInfo
            er.ReadUInt64(); // ExporterInfo

            GrannyUtils.SubreadUInt64Pointer(
                er, ser => { this.FromFileName = ser.ReadStringNT(); });

            var textureCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(er, ser => { });

            var materialCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(er, ser => { });

            var skeletonCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(
                er,
                ser => {
                for (var i = 0; i < skeletonCount; ++i)
                {
                    GrannyUtils.SubreadUInt64Pointer(ser, sser => {
                        var skeleton = new GrannySkeleton();
                        skeleton.Read(sser);
                        this.SkeletonHeaderList.Add(skeleton);
                    });
                }
            });

            var vertexDataCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(er, ser => { });

            var modelHeaderCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(er, ser => { });

            var trackGroupHeaderCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(
                er,
                ser => {
                for (var i = 0; i < trackGroupHeaderCount; ++i)
                {
                    GrannyUtils.SubreadUInt64Pointer(ser, sser => {
                        var trackGroup = new GrannyTrackGroup();
                        trackGroup.Read(ser);
                        this.TrackGroupHeaderList.Add(trackGroup);
                    });
                }
            });

            var animationHeaderCount = er.ReadUInt32();

            GrannyUtils.SubreadUInt64Pointer(
                er,
                ser => {
                for (var i = 0; i < animationHeaderCount; ++i)
                {
                    GrannyUtils.SubreadUInt64Pointer(ser, sser => {
                        var animation = new GrannyAnimation();
                        animation.Read(sser);
                        this.AnimationHeaderList.Add(animation);
                    });
                }
            });
        }